@item MXWARNS
The maximum number of warnings + errors before PSPP halts processing the
-current command file. The default is 100.
+current command file.
+The special value of zero means that all warning situations should be ignored.
+No warnings will be issued, except a single initial warning advising the user
+that warnings will not be given.
+The default value is 100.
@item PROMPT
The command prompt. The default is @samp{PSPP> }.
/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 2009, 2010 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
#include <string.h>
#include <libpspp/compiler.h>
-#include <libpspp/hash.h>
+#include <libpspp/hmap.h>
#include <libpspp/ll.h>
#include <libpspp/message.h>
#include <libpspp/str.h>
+#include <libpspp/hash-functions.h>
#include <data/file-name.h>
#include <data/variable.h>
#include <data/scratch-handle.h>
static void free_handle (struct file_handle *);
static void unname_handle (struct file_handle *);
+/* Hash table of all active locks. */
+static struct hmap locks = HMAP_INITIALIZER (locks);
+
/* File handle initialization routine. */
void
fh_init (void)
/* Information about a file handle's readers or writers. */
struct fh_lock
{
+ struct hmap_node node; /* hmap_node member. */
+
/* Hash key. */
enum fh_referent referent; /* Type of underlying file. */
union
void *aux; /* Owner's auxiliary data. */
};
-/* Hash table of all active locks. */
-static struct hsh_table *locks;
static void make_key (struct fh_lock *, const struct file_handle *,
enum fh_access);
static void free_key (struct fh_lock *);
-static int compare_fh_locks (const void *, const void *, const void *);
-static unsigned int hash_fh_lock (const void *, const void *);
+static int compare_fh_locks (const struct fh_lock *a, const struct fh_lock *b);
+static unsigned int hash_fh_lock (const struct fh_lock *lock);
/* Tries to lock handle H for the given kind of ACCESS and TYPE
of file. Returns a pointer to a struct fh_lock if successful,
fh_lock (struct file_handle *h, enum fh_referent mask UNUSED,
const char *type, enum fh_access access, bool exclusive)
{
- struct fh_lock key, *lock;
- void **lockp;
+ struct fh_lock *key = NULL;
+ size_t hash ;
+ struct fh_lock *lock = NULL;
+ bool found_lock = false;
assert ((fh_get_referent (h) & mask) != 0);
assert (access == FH_ACC_READ || access == FH_ACC_WRITE);
- if (locks == NULL)
- locks = hsh_create (0, compare_fh_locks, hash_fh_lock, NULL, NULL);
+ key = xmalloc (sizeof *key);
+
+ make_key (key, h, access);
+
+ key->open_cnt = 1;
+ key->exclusive = exclusive;
+ key->type = type;
+ key->aux = NULL;
- make_key (&key, h, access);
- lockp = hsh_probe (locks, &key);
- if (*lockp == NULL)
+ hash = hash_fh_lock (key);
+
+ HMAP_FOR_EACH_WITH_HASH (lock, struct fh_lock, node, hash, &locks)
{
- lock = *lockp = xmalloc (sizeof *lock);
- *lock = key;
- lock->open_cnt = 1;
- lock->exclusive = exclusive;
- lock->type = type;
- lock->aux = NULL;
+ if ( 0 == compare_fh_locks (lock, key))
+ {
+ found_lock = true;
+ break;
+ }
}
- else
- {
- free_key (&key);
- lock = *lockp;
+ if ( found_lock )
+ {
if (strcmp (lock->type, type))
{
if (access == FH_ACC_READ)
return NULL;
}
lock->open_cnt++;
+
+ free_key (key);
+ free (key);
+
+ return lock;
}
- return lock;
+ hmap_insert (&locks, &key->node, hash);
+ found_lock = false;
+ HMAP_FOR_EACH_WITH_HASH (lock, struct fh_lock, node, hash, &locks)
+ {
+ if ( 0 == compare_fh_locks (lock, key))
+ {
+ found_lock = true;
+ break;
+ }
+ }
+
+ assert (found_lock);
+
+ return key;
}
/* Releases LOCK that was acquired with fh_lock.
assert (lock->open_cnt > 0);
if (--lock->open_cnt == 0)
{
- hsh_delete (locks, lock);
+ hmap_delete (&locks, &lock->node);
free_key (lock);
free (lock);
return false;
fh_is_locked (const struct file_handle *handle, enum fh_access access)
{
struct fh_lock key;
- bool is_locked;
+ const struct fh_lock *k = NULL;
+ bool is_locked = false;
+ size_t hash ;
make_key (&key, handle, access);
- is_locked = hsh_find (locks, &key) != NULL;
+
+ hash = hash_fh_lock (&key);
+
+
+ HMAP_FOR_EACH_WITH_HASH (k, struct fh_lock, node, hash, &locks)
+ {
+ if ( 0 == compare_fh_locks (k, &key))
+ {
+ is_locked = true;
+ break;
+ }
+ }
+
free_key (&key);
return is_locked;
/* Compares the key fields in struct fh_lock objects A and B and
returns a strcmp()-type result. */
static int
-compare_fh_locks (const void *a_, const void *b_, const void *aux UNUSED)
+compare_fh_locks (const struct fh_lock *a, const struct fh_lock *b)
{
- const struct fh_lock *a = a_;
- const struct fh_lock *b = b_;
-
if (a->referent != b->referent)
return a->referent < b->referent ? -1 : 1;
else if (a->access != b->access)
/* Returns a hash value for LOCK. */
static unsigned int
-hash_fh_lock (const void *lock_, const void *aux UNUSED)
+hash_fh_lock (const struct fh_lock *lock)
{
- const struct fh_lock *lock = lock_;
unsigned int basis;
if (lock->referent == FH_REF_FILE)
basis = fn_hash_identity (lock->u.file);
/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 2010 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
bool
fmt_from_io (int io, enum fmt_type *fmt_type)
{
- enum fmt_type type;
-
- for (type = 0; type < FMT_NUMBER_OF_FORMATS; type++)
- if (get_fmt_desc (type)->io == io)
- {
- *fmt_type = type;
- return true;
- }
- return false;
+ switch (io)
+ {
+#define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) \
+ case IO: \
+ *fmt_type = FMT_##NAME; \
+ return true;
+#include "format.def"
+ default:
+ return false;
+ }
}
/* Returns true if TYPE may be used as an input format,
/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 2010 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
/* Legacy numeric formats. */
FMT (N, N, 1, 1, 16, FMT_CAT_LEGACY)
-FMT (Z, Z, 1, 1, 16, FMT_CAT_LEGACY)
+FMT (Z, Z, 1, 1, 15, FMT_CAT_LEGACY)
/* Binary and hexadecimal formats. */
FMT (P, P, 1, 1, 8, FMT_CAT_BINARY)
/* 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.) */
+ 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
+ issued.
+*/
void
settings_set_max_messages (enum msg_severity severity, int max)
{
assert (severity < MSG_N_SEVERITIES);
+
+ if (severity == MSG_S_WARNING)
+ {
+ 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);
+ }
+ else if ( the_settings.max_messages [MSG_S_WARNING] == 0)
+ {
+ msg_ui_disable_warnings (false);
+ the_settings.max_messages[MSG_S_WARNING] = max;
+ msg (MW, _("Warnings re-enabled. %d warnings will be issued before aborting syntax processing."), max);
+ }
+ }
+
the_settings.max_messages[severity] = max;
}
if (e)
{
- msg (SE, _("COLUMN subcommand multiply specified."));
+ msg (SE, _("%s subcommand may be given at most once."), "COLUMN");
expr_free (e);
return CMD_CASCADING_FAILURE;
}
&& array_arg_cnt % f->array_granularity != 0)
{
if (f->array_granularity == 2)
- msg (SE, _("%s must have even number of arguments in list."),
+ msg (SE, _("%s must have an even number of arguments in list."),
f->prototype);
else
msg (SE, _("%s must have multiple of %d arguments in list."),
/* Done. */
+ free (corr->vars);
free (corr);
+
return ok ? CMD_SUCCESS : CMD_CASCADING_FAILURE;
error:
+ free (corr->vars);
free (corr);
return CMD_FAILURE;
}
tab_text (chisq, 1, 0, TAB_RIGHT | TAT_TITLE, _("Value"));
tab_text (chisq, 2, 0, TAB_RIGHT | TAT_TITLE, _("df"));
tab_text (chisq, 3, 0, TAB_RIGHT | TAT_TITLE,
- _("Asymp. Sig. (2-sided)"));
+ _("Asymp. Sig. (2-tailed)"));
tab_text (chisq, 4, 0, TAB_RIGHT | TAT_TITLE,
- _("Exact Sig. (2-sided)"));
+ _("Exact Sig. (2-tailed)"));
tab_text (chisq, 5, 0, TAB_RIGHT | TAT_TITLE,
- _("Exact Sig. (1-sided)"));
+ _("Exact Sig. (1-tailed)"));
tab_offset (chisq, 0, 1);
return chisq;
#include <libpspp/str.h>
#include <libpspp/version.h>
+#include <data/settings.h>
#include "gl/progname.h"
#include "gl/xalloc.h"
return ds_cstr (&s);
}
\f
+
+/* Number of messages reported, by severity level. */
+static int counts[MSG_N_SEVERITIES];
+
+/* True after the maximum number of errors or warnings has been exceeded. */
+static bool too_many_errors;
+
+/* True after the maximum number of notes has been exceeded. */
+static bool too_many_notes;
+
+/* True iff warnings have been explicitly disabled (MXWARNS = 0) */
+static bool warnings_off = false;
+
+/* Checks whether we've had so many errors that it's time to quit
+ processing this syntax file. */
+bool
+msg_ui_too_many_errors (void)
+{
+ return too_many_errors;
+}
+
+void
+msg_ui_disable_warnings (bool x)
+{
+ warnings_off = x;
+}
+
+
+void
+msg_ui_reset_counts (void)
+{
+ int i;
+
+ for (i = 0; i < MSG_N_SEVERITIES; i++)
+ counts[i] = 0;
+ too_many_errors = false;
+ too_many_notes = false;
+}
+
+bool
+msg_ui_any_errors (void)
+{
+ return counts[MSG_S_ERROR] > 0;
+}
+
+static void
+submit_note (char *s)
+{
+ struct msg m;
+
+ m.category = MSG_C_GENERAL;
+ m.severity = MSG_S_NOTE;
+ m.where.file_name = NULL;
+ m.where.line_number = -1;
+ m.text = s;
+ msg_handler (&m);
+ free (s);
+}
+
+
+
+static void
+process_msg (const struct msg *m)
+{
+ int n_msgs, max_msgs;
+
+
+ if (too_many_errors
+ || (too_many_notes && m->severity == MSG_S_NOTE)
+ || (warnings_off && m->severity == MSG_S_WARNING) )
+ return;
+
+ msg_handler (m);
+
+ counts[m->severity]++;
+ max_msgs = settings_get_max_messages (m->severity);
+ n_msgs = counts[m->severity];
+ if (m->severity == MSG_S_WARNING)
+ n_msgs += counts[MSG_S_ERROR];
+ if (n_msgs > max_msgs)
+ {
+ if (m->severity == MSG_S_NOTE)
+ {
+ too_many_notes = true;
+ submit_note (xasprintf (_("Notes (%d) exceed limit (%d). "
+ "Suppressing further notes."),
+ n_msgs, max_msgs));
+ }
+ else
+ {
+ too_many_errors = true;
+ if (m->severity == MSG_S_WARNING)
+ submit_note (xasprintf (_("Warnings (%d) exceed limit (%d). Syntax processing will be halted."),
+ n_msgs, max_msgs));
+ else
+ submit_note (xasprintf (_("Errors (%d) exceed limit (%d). Syntax processing will be halted."),
+ n_msgs, max_msgs));
+ }
+ }
+}
+
+
/* Emits M as an error message.
Frees allocated data in M. */
void
}
if (!messages_disabled)
- msg_handler (m);
+ process_msg (m);
+
free (m->text);
}
_exit (EXIT_FAILURE);
}
+
void msg_push_msg_locator (const struct msg_locator *);
void msg_pop_msg_locator (const struct msg_locator *);
+bool msg_ui_too_many_errors (void);
+void msg_ui_reset_counts (void);
+bool msg_ui_any_errors (void);
+void msg_ui_disable_warnings (bool);
+
/* Used in panic situations only. */
void request_bug_report_and_abort (const char *msg) NO_RETURN;
+
#endif /* message.h */
PsppireDataStore *ds = PSPPIRE_DATA_STORE (model);
if ( col >= psppire_dict_get_var_cnt (ds->dict) )
- return g_locale_to_utf8 (null_var_name, -1, 0, 0, 0);
+ return xstrdup (gettext (null_var_name));
pv = psppire_dict_get_variable (ds->dict, col);
}
+\f
+
+/* Delete the currently selected text */
+static void
+on_edit_delete (PsppireSyntaxWindow *sw)
+{
+ GtkTextIter begin, end;
+ GtkTextBuffer *buffer = GTK_TEXT_BUFFER (sw->buffer);
+
+ if ( gtk_text_buffer_get_selection_bounds (buffer, &begin, &end) )
+ gtk_text_buffer_delete (buffer, &begin, &end);
+}
+
+
+/* The syntax editor's clipboard deals only with text */
+enum {
+ SELECT_FMT_NULL,
+ SELECT_FMT_TEXT,
+};
+
+
+static void
+selection_changed (PsppireSyntaxWindow *sw)
+{
+ gboolean sel = gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER (sw->buffer));
+
+ gtk_action_set_sensitive (sw->edit_copy, sel);
+ gtk_action_set_sensitive (sw->edit_cut, sel);
+ gtk_action_set_sensitive (sw->edit_delete, sel);
+}
+
+/* The callback which runs when something request clipboard data */
+static void
+clipboard_get_cb (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ guint info,
+ gpointer data)
+{
+ PsppireSyntaxWindow *sw = data;
+ g_assert (info == SELECT_FMT_TEXT);
+
+ gtk_selection_data_set (selection_data, selection_data->target,
+ 8,
+ (const guchar *) sw->cliptext, strlen (sw->cliptext));
+
+}
+
+static void
+clipboard_clear_cb (GtkClipboard *clipboard,
+ gpointer data)
+{
+ PsppireSyntaxWindow *sw = data;
+ g_free (sw->cliptext);
+ sw->cliptext = NULL;
+}
+
+
+static const GtkTargetEntry targets[] = {
+ { "UTF8_STRING", 0, SELECT_FMT_TEXT },
+ { "STRING", 0, SELECT_FMT_TEXT },
+ { "TEXT", 0, SELECT_FMT_TEXT },
+ { "COMPOUND_TEXT", 0, SELECT_FMT_TEXT },
+ { "text/plain;charset=utf-8", 0, SELECT_FMT_TEXT },
+ { "text/plain", 0, SELECT_FMT_TEXT },
+};
+
+
+/*
+ Store a clip containing the currently selected text.
+ Returns true iff something was set.
+ As a side effect, begin and end will be set to indicate
+ the limits of the selected text.
+*/
+static gboolean
+set_clip (PsppireSyntaxWindow *sw, GtkTextIter *begin, GtkTextIter *end)
+{
+ GtkClipboard *clipboard ;
+ GtkTextBuffer *buffer = GTK_TEXT_BUFFER (sw->buffer);
+
+ if ( ! gtk_text_buffer_get_selection_bounds (buffer, begin, end) )
+ return FALSE;
+
+ g_free (sw->cliptext);
+ sw->cliptext = gtk_text_buffer_get_text (buffer, begin, end, FALSE);
+
+ clipboard =
+ gtk_widget_get_clipboard (GTK_WIDGET (sw), GDK_SELECTION_CLIPBOARD);
+
+ if (!gtk_clipboard_set_with_owner (clipboard, targets,
+ G_N_ELEMENTS (targets),
+ clipboard_get_cb, clipboard_clear_cb,
+ G_OBJECT (sw)))
+ clipboard_clear_cb (clipboard, sw);
+
+ return TRUE;
+}
+
+static void
+on_edit_cut (PsppireSyntaxWindow *sw)
+{
+ GtkTextIter begin, end;
+
+ if ( set_clip (sw, &begin, &end))
+ gtk_text_buffer_delete (GTK_TEXT_BUFFER (sw->buffer), &begin, &end);
+}
+
+static void
+on_edit_copy (PsppireSyntaxWindow *sw)
+{
+ GtkTextIter begin, end;
+
+ set_clip (sw, &begin, &end);
+}
+
+
+/* A callback for when the clipboard contents have been received */
+static void
+contents_received_callback (GtkClipboard *clipboard,
+ GtkSelectionData *sd,
+ gpointer data)
+{
+ gchar *c;
+ PsppireSyntaxWindow *syntax_window = data;
+
+ if ( sd->length < 0 )
+ return;
+
+ if ( sd->type != gdk_atom_intern ("UTF8_STRING", FALSE))
+ return;
+
+ c = (gchar *) sd->data;
+
+ gtk_text_buffer_insert_at_cursor (GTK_TEXT_BUFFER (syntax_window->buffer),
+ (gchar *) sd->data,
+ sd->length);
+
+}
+
+static void
+on_edit_paste (PsppireSyntaxWindow *sw)
+{
+ GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (sw));
+ GtkClipboard *clipboard =
+ gtk_clipboard_get_for_display (display, GDK_SELECTION_CLIPBOARD);
+
+ gtk_clipboard_request_contents (clipboard,
+ gdk_atom_intern ("UTF8_STRING", TRUE),
+ contents_received_callback,
+ sw);
+}
+
+static void
+on_owner_change (GtkClipboard *clip, GdkEventOwnerChange *event, gpointer data)
+{
+ gint i;
+ gboolean compatible_target = FALSE;
+ PsppireSyntaxWindow *sw = PSPPIRE_SYNTAX_WINDOW (data);
+
+ for (i = 0 ; i < sizeof (targets) / sizeof (targets[0]) ; ++i)
+ {
+ GdkAtom atom = gdk_atom_intern (targets[i].target, TRUE);
+ if ( gtk_clipboard_wait_is_target_available (clip, atom))
+ {
+ compatible_target = TRUE;
+ break;
+ }
+ }
+
+ gtk_action_set_sensitive (sw->edit_paste, compatible_target);
+}
+
+
+\f
+
/* Parse and execute all the text in the buffer */
static void
on_run_all (GtkMenuItem *menuitem, gpointer user_data)
PsppireSyntaxWindowClass *class
= PSPPIRE_SYNTAX_WINDOW_CLASS (G_OBJECT_GET_CLASS (window));
+ GtkClipboard *clip_selection = gtk_widget_get_clipboard (GTK_WIDGET (window), GDK_SELECTION_CLIPBOARD);
+ GtkClipboard *clip_primary = gtk_widget_get_clipboard (GTK_WIDGET (window), GDK_SELECTION_PRIMARY);
+
window->print_settings = NULL;
window->undo_menuitem = get_action_assert (xml, "edit_undo");
window->redo_menuitem = get_action_assert (xml, "edit_redo");
"highlight-matching-brackets", TRUE,
NULL);
-
g_object_set (text_view,
"show-line-numbers", TRUE,
"show-line-marks", TRUE,
"indent-width", 4,
"highlight-current-line", TRUE,
NULL);
+
+ g_signal_connect_swapped (clip_primary, "owner-change", G_CALLBACK (selection_changed), window);
+
+ g_signal_connect (clip_selection, "owner-change", G_CALLBACK (on_owner_change), window);
+
+ window->cliptext = NULL;
+
+ window->edit_delete = get_action_assert (xml, "edit_delete");
+ window->edit_copy = get_action_assert (xml, "edit_copy");
+ window->edit_cut = get_action_assert (xml, "edit_cut");
+ window->edit_paste = get_action_assert (xml, "edit_paste");
+
window->lexer = lex_create (the_source_stream);
window->sb = get_widget_assert (xml, "statusbar2");
G_CALLBACK (on_quit),
window);
+ g_signal_connect_swapped (window->edit_delete,
+ "activate",
+ G_CALLBACK (on_edit_delete),
+ window);
+
+ g_signal_connect_swapped (window->edit_copy,
+ "activate",
+ G_CALLBACK (on_edit_copy),
+ window);
+
+ g_signal_connect_swapped (window->edit_cut,
+ "activate",
+ G_CALLBACK (on_edit_cut),
+ window);
+
+ g_signal_connect_swapped (window->edit_paste,
+ "activate",
+ G_CALLBACK (on_edit_paste),
+ window);
+
g_signal_connect (get_action_assert (xml,"run_all"),
"activate",
G_CALLBACK (on_run_all),
window);
-
g_signal_connect (get_action_assert (xml,"run_selection"),
"activate",
G_CALLBACK (on_run_selection),
}
+
+
+
GtkWidget*
psppire_syntax_window_new (void)
{
GtkSourcePrintCompositor *compositor;
GtkAction *undo_menuitem;
GtkAction *redo_menuitem;
+
+ gchar *cliptext;
+
+ GtkAction *edit_cut;
+ GtkAction *edit_copy;
+ GtkAction *edit_delete;
+ GtkAction *edit_paste;
};
struct _PsppireSyntaxWindowClass
<child>
<object class="GtkAction" id="edit_cut">
<property name="stock-id">gtk-cut</property>
- <property name="name">cut</property>
+ <property name="name">edit_cut</property>
+ <property name="sensitive">false</property>
</object>
</child>
<child>
<object class="GtkAction" id="edit_copy">
<property name="stock-id">gtk-copy</property>
- <property name="name">copy</property>
+ <property name="name">edit_copy</property>
+ <property name="sensitive">false</property>
</object>
</child>
<child>
<object class="GtkAction" id="edit_paste">
<property name="stock-id">gtk-paste</property>
- <property name="name">paste</property>
+ <property name="name">edit_paste</property>
+ <property name="sensitive">false</property>
</object>
</child>
<child>
<object class="GtkAction" id="edit_delete">
<property name="stock-id">gtk-delete</property>
- <property name="name">delete</property>
+ <property name="name">edit_delete</property>
+ <property name="sensitive">false</property>
</object>
</child>
<child>
#include <gtk/gtk.h>
-
+#include "widget-io.h"
#include "checkbox-treeview.h"
#include "descriptives-dialog.h"
\f
/* The "intro" page of the assistant. */
-static void on_intro_amount_changed (GtkToggleButton *button,
- struct import_assistant *);
+static void on_intro_amount_changed (struct import_assistant *);
/* Initializes IA's intro substructure. */
static void
GtkBuilder *builder = ia->asst.builder;
struct intro_page *p = &ia->intro;
struct string s;
+ GtkWidget *hbox_n_cases ;
+ GtkWidget *hbox_percent ;
+ GtkWidget *table ;
+
+
+ p->n_cases_spin = gtk_spin_button_new_with_range (0, INT_MAX, 100);
+
+ hbox_n_cases = widget_scanf (_("Only the first %4d cases"), &p->n_cases_spin);
+
+ table = get_widget_assert (builder, "button-table");
+
+ gtk_table_attach_defaults (GTK_TABLE (table), hbox_n_cases,
+ 1, 2,
+ 1, 2);
+
+ p->percent_spin = gtk_spin_button_new_with_range (0, 100, 10);
+
+ hbox_percent = widget_scanf (_("Only the first %3d %% of file (approximately)"), &p->percent_spin);
+
+ gtk_table_attach_defaults (GTK_TABLE (table), hbox_percent,
+ 1, 2,
+ 2, 3);
p->page = add_page_to_assistant (ia, get_widget_assert (builder, "Intro"),
GTK_ASSISTANT_PAGE_INTRO);
+
p->all_cases_button = get_widget_assert (builder, "import-all-cases");
+
p->n_cases_button = get_widget_assert (builder, "import-n-cases");
- p->n_cases_spin = get_widget_assert (builder, "n-cases-spin");
+
p->percent_button = get_widget_assert (builder, "import-percent");
- p->percent_spin = get_widget_assert (builder, "percent-spin");
- g_signal_connect (p->all_cases_button, "toggled",
+
+ g_signal_connect_swapped (p->all_cases_button, "toggled",
G_CALLBACK (on_intro_amount_changed), ia);
- g_signal_connect (p->n_cases_button, "toggled",
+ g_signal_connect_swapped (p->n_cases_button, "toggled",
G_CALLBACK (on_intro_amount_changed), ia);
- g_signal_connect (p->percent_button, "toggled",
+ g_signal_connect_swapped (p->percent_button, "toggled",
G_CALLBACK (on_intro_amount_changed), ia);
+ on_intro_amount_changed (ia);
+
ds_init_empty (&s);
ds_put_cstr (&s, _("This assistant will guide you through the process of "
"importing data into PSPP from a text file with one line "
/* Called when one of the radio buttons is clicked. */
static void
-on_intro_amount_changed (GtkToggleButton *button UNUSED,
- struct import_assistant *ia)
+on_intro_amount_changed (struct import_assistant *ia)
{
struct intro_page *p = &ia->intro;
gtk_toggle_button_get_active (
GTK_TOGGLE_BUTTON (p->n_cases_button)));
- gtk_widget_set_sensitive (ia->intro.percent_spin,
+ gtk_widget_set_sensitive (p->percent_spin,
gtk_toggle_button_get_active (
GTK_TOGGLE_BUTTON (p->percent_button)));
}
size_t max_line_length;
gint content_width, header_width;
size_t i;
+ gchar *title = _("Text");
make_tree_view (ia, 0, &tree_view);
- column = gtk_tree_view_column_new_with_attributes (
- "Text", ia->asst.fixed_renderer,
- "text", TEXT_IMPORT_MODEL_COLUMN_LINE,
- (void *) NULL);
+ column = gtk_tree_view_column_new_with_attributes
+ (
+ title, ia->asst.fixed_renderer,
+ "text", TEXT_IMPORT_MODEL_COLUMN_LINE,
+ (void *) NULL
+ );
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
max_line_length = 0;
content_width = get_monospace_width (tree_view, ia->asst.fixed_renderer,
max_line_length);
- header_width = get_string_width (tree_view, ia->asst.prop_renderer, "Text");
+ header_width = get_string_width (tree_view, ia->asst.prop_renderer, title);
gtk_tree_view_column_set_fixed_width (column, MAX (content_width,
header_width));
gtk_tree_view_append_column (tree_view, column);
GtkTreeViewColumn *column;
column = gtk_tree_view_column_new_with_attributes (
- "Line", ia->asst.prop_renderer,
+ _("Line"), ia->asst.prop_renderer,
"text", TEXT_IMPORT_MODEL_COLUMN_LINE_NUMBER,
(void *) NULL);
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="left_padding">12</property>
<child>
- <object class="GtkVBox" id="vbox1">
+ <object class="GtkTable" id="button-table">
<property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">2</property>
<child>
<object class="GtkRadioButton" id="import-all-cases">
- <property name="label" translatable="yes">All cases</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
- <property name="position">0</property>
+ <property name="x_options"></property>
</packing>
</child>
<child>
- <object class="GtkHBox" id="hbox1">
+ <object class="GtkRadioButton" id="import-n-cases">
<property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkRadioButton" id="import-n-cases">
- <property name="label" translatable="yes">Only first </property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <property name="group">import-all-cases</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkSpinButton" id="n-cases-spin">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="adjustment">adjustment2</property>
- <property name="climb_rate">10</property>
- <property name="snap_to_ticks">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes"> cases</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">import-all-cases</property>
</object>
<packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options"></property>
</packing>
</child>
<child>
- <object class="GtkHBox" id="hbox3">
+ <object class="GtkRadioButton" id="import-percent">
<property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkRadioButton" id="import-percent">
- <property name="label" translatable="yes">Only first </property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <property name="group">import-all-cases</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkSpinButton" id="percent-spin">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="adjustment">adjustment1</property>
- <property name="snap_to_ticks">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">% of file (approximately)</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">import-all-cases</property>
</object>
<packing>
- <property name="position">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">All cases</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
</packing>
</child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
</object>
</child>
</object>
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
- <property name="page_size">0</property>
</object>
<object class="GtkAdjustment" id="adjustment2">
<property name="value">1000</property>
<property name="upper">100000000</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
- <property name="page_size">0</property>
</object>
</interface>
#include <config.h>
-#include "ui/terminal/msg-ui.h"
-
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "data/settings.h"
-#include "libpspp/getl.h"
+#include "msg-ui.h"
#include "libpspp/message.h"
#include "libpspp/msg-locator.h"
-#include "libpspp/str.h"
-#include "output/journal.h"
-#include "output/driver.h"
-#include "output/tab.h"
#include "output/message-item.h"
-#include "gl/unilbrk.h"
-#include "gl/localcharset.h"
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-#define N_(msgid) msgid
-
-/* Number of messages reported, by severity level. */
-static int counts[MSG_N_SEVERITIES];
-
-/* True after the maximum number of errors or warnings has been exceeded. */
-static bool too_many_errors;
-
-/* True after the maximum number of notes has been exceeded. */
-static bool too_many_notes;
-
-static void handle_msg (const struct msg *);
+static void
+handle_msg (const struct msg *m)
+{
+ message_item_submit (message_item_create (m));
+}
void
msg_ui_init (struct source_stream *ss)
msg_done ();
msg_locator_done ();
}
-
-/* Checks whether we've had so many errors that it's time to quit
- processing this syntax file. */
-bool
-msg_ui_too_many_errors (void)
-{
- return too_many_errors;
-}
-
-void
-msg_ui_reset_counts (void)
-{
- int i;
-
- for (i = 0; i < MSG_N_SEVERITIES; i++)
- counts[i] = 0;
- too_many_errors = false;
- too_many_notes = false;
-}
-
-bool
-msg_ui_any_errors (void)
-{
- return counts[MSG_S_ERROR] > 0;
-}
-
-static void
-submit_note (char *s)
-{
- struct msg m;
-
- m.category = MSG_C_GENERAL;
- m.severity = MSG_S_NOTE;
- m.where.file_name = NULL;
- m.where.line_number = -1;
- m.text = s;
- message_item_submit (message_item_create (&m));
- free (s);
-}
-
-static void
-handle_msg (const struct msg *m)
-{
- int n_msgs, max_msgs;
-
- if (too_many_errors || (too_many_notes && m->severity == MSG_S_NOTE))
- return;
-
- message_item_submit (message_item_create (m));
-
- counts[m->severity]++;
- max_msgs = settings_get_max_messages (m->severity);
- n_msgs = counts[m->severity];
- if (m->severity == MSG_S_WARNING)
- n_msgs += counts[MSG_S_ERROR];
- if (n_msgs > max_msgs)
- {
- if (m->severity == MSG_S_NOTE)
- {
- too_many_notes = true;
- submit_note (xasprintf (_("Notes (%d) exceed limit (%d). "
- "Suppressing further notes."),
- n_msgs, max_msgs));
- }
- else
- {
- too_many_errors = true;
- if (m->severity == MSG_S_WARNING)
- submit_note (xasprintf (_("Warnings (%d) exceed limit (%d)."),
- n_msgs, max_msgs));
- else
- submit_note (xasprintf (_("Errors (%d) exceed limit (%d)."),
- n_msgs, max_msgs));
- }
- }
-}
void msg_ui_set_error_file (FILE *);
void msg_ui_init (struct source_stream *);
void msg_ui_done (void);
-bool msg_ui_too_many_errors (void);
-void msg_ui_reset_counts (void);
-bool msg_ui_any_errors (void);
#endif /* msg-ui.h */
RANGE(number, number, number[, number, number]...)
RANGE(string, string, string[, string, string]...).]],
[[range(1, 2)], [error],
- [error: DEBUG EVALUATE: RANGE(number, number, number[, number, number]...) must have even number of arguments in list.]],
+ [error: DEBUG EVALUATE: RANGE(number, number, number[, number, number]...) must have an even number of arguments in list.]],
[[range(1, 2, 3, 4)], [error],
- [error: DEBUG EVALUATE: RANGE(number, number, number[, number, number]...) must have even number of arguments in list.]],
+ [error: DEBUG EVALUATE: RANGE(number, number, number[, number, number]...) must have an even number of arguments in list.]],
[[range(1, 2, 3, 4, 5, 6)], [error],
- [error: DEBUG EVALUATE: RANGE(number, number, number[, number, number]...) must have even number of arguments in list.]],
+ [error: DEBUG EVALUATE: RANGE(number, number, number[, number, number]...) must have an even number of arguments in list.]],
[[range('1', 2, 3)], [error],
[error: DEBUG EVALUATE: Function invocation range(string, number, number) does not match any known function. Candidates are:
RANGE(number, number, number[, number, number]...)
RANGE(number, number, number[, number, number]...)
RANGE(string, string, string[, string, string]...).]],
[[range('1', '2')], [error],
- [error: DEBUG EVALUATE: RANGE(string, string, string[, string, string]...) must have even number of arguments in list.]],
+ [error: DEBUG EVALUATE: RANGE(string, string, string[, string, string]...) must have an even number of arguments in list.]],
[[range('1', '2', '3', '4')], [error],
- [error: DEBUG EVALUATE: RANGE(string, string, string[, string, string]...) must have even number of arguments in list.]],
+ [error: DEBUG EVALUATE: RANGE(string, string, string[, string, string]...) must have an even number of arguments in list.]],
[[range('1', '2', '3', '4', '5', '6')], [error],
- [error: DEBUG EVALUATE: RANGE(string, string, string[, string, string]...) must have even number of arguments in list.]],
+ [error: DEBUG EVALUATE: RANGE(string, string, string[, string, string]...) must have an even number of arguments in list.]],
[[range(1, '2', '3')], [error],
[error: DEBUG EVALUATE: Function invocation range(number, string, string) does not match any known function. Candidates are:
RANGE(number, number, number[, number, number]...)
Total,2.0,2.0,4.0
Table: Chi-square tests.
-Statistic,Value,df,Asymp. Sig. (2-sided)
+Statistic,Value,df,Asymp. Sig. (2-tailed)
Pearson Chi-Square,2.00,2,.37
Likelihood Ratio,2.77,2,.25
Linear-by-Linear Association,.27,1,.60
,66.7%,33.3%,100.0%
Table: Chi-square tests.
-Statistic,Value,df,Asymp. Sig. (2-sided),Exact Sig. (2-sided),Exact Sig. (1-sided)
+Statistic,Value,df,Asymp. Sig. (2-tailed),Exact Sig. (2-tailed),Exact Sig. (1-tailed)
Pearson Chi-Square,.38,1,.54,,
Likelihood Ratio,.37,1,.54,,
Fisher's Exact Test,,,,1.00,.60
,25.0%,75.0%,100.0%
Table: Chi-square tests.
-Statistic,Value,df,Asymp. Sig. (2-sided),Exact Sig. (2-sided),Exact Sig. (1-sided)
+Statistic,Value,df,Asymp. Sig. (2-tailed),Exact Sig. (2-tailed),Exact Sig. (1-tailed)
Pearson Chi-Square,.44,1,.50,,
Likelihood Ratio,.68,1,.41,,
Fisher's Exact Test,,,,1.00,.75
x,3,2.00,1.00,1.00,3.00
])
AT_CLEANUP
+
+
+
+AT_SETUP([SET MXWARNS])
+dnl Make sure that syntax processing stops and that
+dnl a warning is issued when the MXWARNS figure is
+dnl exceeded.
+AT_DATA([set.pspp], [dnl
+set mxwarns=2.
+data list notable list /x (f8.2) y (f8.2).
+begin data
+1 2
+3 r
+5 x
+q 8
+9 9
+3 x
+w w
+end data.
+
+comment The following line should not be executed.
+list.
+])
+
+AT_CHECK([pspp -O format=csv set.pspp], [0], [dnl
+"set.pspp:5: warning: (column 3, F field) Field contents are not numeric."
+
+"set.pspp:6: warning: (column 3, F field) Field contents are not numeric."
+
+"set.pspp:7: warning: (column 1, F field) Field contents are not numeric."
+
+note: Warnings (3) exceed limit (2). Syntax processing will be halted.
+])
+
+AT_CLEANUP
+
+
+
+
+AT_SETUP([SET MXWARNS special case zero])
+dnl Make sure that MXWARNS interprets zero as infinity.
+AT_DATA([mxwarns.pspp], [dnl
+set mxwarns=0.
+data list notable list /x (f8.2) y (f8.2) z *.
+begin data
+1 2 3
+3 r 3
+5 x 3
+q 8 4
+9 9 4
+3 x 4
+w w 4
+end data.
+
+list.
+])
+
+AT_CHECK([pspp -O format=csv mxwarns.pspp], [0],
+[warning: MXWARNS set to zero. No further warnings will be given even when potentially problematic situations are encountered.
+
+Table: Data List
+x,y,z
+1.00,2.00,3.00
+3.00,. ,3.00
+5.00,. ,3.00
+. ,8.00,4.00
+9.00,9.00,4.00
+3.00,. ,4.00
+. ,. ,4.00
+])
+
+AT_CLEANUP