You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
-/* AIX requires this to be the first thing in the file. */
#include <config.h>
-#if __GNUC__
-#define alloca __builtin_alloca
-#else
-#if HAVE_ALLOCA_H
-#include <alloca.h>
-#else
-#ifdef _AIX
-#pragma alloca
-#else
-#ifndef alloca /* predefined by HP cc +Olibcalls */
-char *alloca ();
-#endif
-#endif
-#endif
-#endif
-
-#include <assert.h>
+#include "error.h"
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "alloc.h"
#include "command.h"
-#include "error.h"
#include "getline.h"
+#include "glob.h"
+#include "lexer.h"
#include "main.h"
#include "output.h"
#include "settings.h"
#include "str.h"
#include "var.h"
+#include "version.h"
int err_error_count;
int err_warning_count;
void
tmsg (int class, const char *title, const char *format, ...)
{
- char buf[1024];
-
- /* Format the message into BUF. */
- {
- va_list args;
+ struct error e;
+ va_list args;
- va_start (args, format);
- vsnprintf (buf, 1024, format, args);
- va_end (args);
- }
-
- /* Output the message. */
- {
- struct error e;
+ e.class = class;
+ err_location (&e.where);
+ e.title = title;
- e.class = class;
- err_location (&e.where);
- e.title = title;
- e.text = buf;
- err_vmsg (&e);
- }
+ va_start (args, format);
+ err_vmsg (&e, format, args);
+ va_end (args);
}
/* Writes error message in CLASS, with text FORMAT, formatted with
void
msg (int class, const char *format, ...)
{
- char buf[1024];
-
- /* Format the message into BUF. */
- {
- va_list args;
+ struct error e;
+ va_list args;
- va_start (args, format);
- vsnprintf (buf, 1024, format, args);
- va_end (args);
- }
-
- /* Output the message. */
- {
- struct error e;
+ e.class = class;
+ err_location (&e.where);
+ e.title = NULL;
- e.class = class;
- err_location (&e.where);
- e.title = NULL;
- e.text = buf;
- err_vmsg (&e);
- }
+ va_start (args, format);
+ err_vmsg (&e, format, args);
+ va_end (args);
}
/* Terminate due to fatal error in input. */
{
int error_class = getl_interactive ? MM : FE;
- if (set_errorbreak && err_error_count)
+ if (get_errorbreak() && err_error_count)
msg (error_class, _("Terminating execution of syntax file due to error."));
- else if (err_error_count > set_mxerrs)
+ else if (err_error_count > get_mxerrs() )
msg (error_class, _("Errors (%d) exceeds limit (%d)."),
- err_error_count, set_mxerrs);
- else if (err_error_count + err_warning_count > set_mxwarns)
+ err_error_count, get_mxerrs());
+ else if (err_error_count + err_warning_count > get_mxwarns() )
msg (error_class, _("Warnings (%d) exceed limit (%d)."),
- err_error_count + err_warning_count, set_mxwarns);
+ err_error_count + err_warning_count, get_mxwarns() );
else
return;
getl_close_all ();
}
-#if __CHECKER__
-static void induce_segfault (void);
-#endif
-
/* Some machines are broken. Compensate. */
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
{
terminating = 1;
+ lex_done();
getl_uninitialize ();
+ free(file_loc);
outp_done ();
+ done_glob();
-#if __CHECKER__
- if (!success)
- induce_segfault ();
-#endif
exit (success ? EXIT_SUCCESS : EXIT_FAILURE);
}
void (*func) (const char *), unsigned width);
void
-err_vmsg (const struct error *e)
+err_vmsg (const struct error *e, const char *format, va_list args)
{
/* Class flags. */
enum
/* Describes one class of error. */
struct error_class
{
- int flags; /* Zero or more of MSG_*. */
+ int flags; /* Zero or more of ERR_*. */
int *count; /* Counting category. */
const char *banner; /* Banner. */
};
{0, NULL, N_("installation error")}, /* IE */
{2, NULL, N_("installation error")}, /* IS */
- {2, NULL, N_("error")}, /* DE */
- {2, NULL, N_("warning")}, /* DW */
+ {2, &err_error_count, N_("error")}, /* DE */
+ {2, &err_warning_count, N_("warning")}, /* DW */
- {0, NULL, N_("error")}, /* ME */
- {0, NULL, N_("warning")}, /* MW */
+ {0, &err_error_count, N_("error")}, /* ME */
+ {0, &err_warning_count, N_("warning")}, /* MW */
{0, NULL, N_("note")}, /* MM */
};
class &= ERR_CLASS_MASK;
assert (class >= 0 && class < ERR_CLASS_COUNT);
- assert (e->text != NULL);
+ assert (format != NULL);
- ds_init (NULL, &msg, 64);
+ ds_init (&msg, 64);
if (e->where.filename && (error_classes[class].flags & ERR_WITH_FILE))
{
ds_printf (&msg, "%s:", e->where.filename);
if (e->where.line_number != -1)
ds_printf (&msg, "%d:", e->where.line_number);
- ds_putchar (&msg, ' ');
+ ds_putc (&msg, ' ');
}
ds_printf (&msg, "%s: ", gettext (error_classes[class].banner));
ds_printf (&msg, "%s: ", cur_proc);
if (e->title)
- ds_concat (&msg, e->title);
+ ds_puts (&msg, e->title);
- ds_concat (&msg, e->text);
+ ds_vprintf (&msg, format, args);
/* FIXME: Check set_messages and set_errors to determine where to
send errors and messages.
Please note that this is not trivial. We have to avoid an
infinite loop in reporting errors that originate in the output
section. */
- dump_message (ds_value (&msg), 8, puts_stdout, set_viewwidth);
+ dump_message (ds_c_str (&msg), 8, puts_stdout, get_viewwidth());
ds_destroy (&msg);
puts (s);
}
+/* Returns 1 if the line must be broken here */
+static int
+compulsory_break(int c)
+{
+ return ( c == '\n' );
+}
+
/* Returns 1 if C is a `break character', that is, if it is a good
place to break a message into lines. */
static inline int
char_is_break (int quote, int c)
{
return ((quote && c == DIR_SEPARATOR)
- || (!quote && (isspace (c) || c == '-' || c == '/')));
+ || (!quote && (isspace (c) || c == '-' || c == '/')));
}
/* Returns 1 if C is a break character where the break should be made
if (indent > width / 3)
indent = width / 3;
- buf = local_alloc (width + 1);
+ buf = local_alloc (width + 2);
/* Advance WIDTH characters into MSG.
If that's a valid breakpoint, keep it; otherwise, back up.
Output the line. */
- for (cp = msg; (unsigned) (cp - msg) < width - 1; cp++)
+ for (cp = msg; (unsigned) (cp - msg) < width - 1 &&
+ ! compulsory_break(*cp); cp++)
if (*cp == '"')
quote ^= 1;
*cp = c;
}
+
/* Repeat above procedure for remaining lines. */
for (;;)
{
+ static int hard_break=0;
+
+ int idx=0;
char *cp2;
/* Advance past whitespace. */
- while (isspace ((unsigned char) *cp))
+ if (! hard_break )
+ while ( isspace ((unsigned char) *cp) )
+ cp++;
+ else
cp++;
+
if (*cp == 0)
- break;
+ break;
+
/* Advance WIDTH - INDENT characters. */
- for (cp2 = cp; (unsigned) (cp2 - cp) < width - indent && *cp2; cp2++)
+ for (cp2 = cp; (unsigned) (cp2 - cp) < width - indent &&
+ *cp2 && !compulsory_break(*cp2); cp2++)
if (*cp2 == '"')
quote ^= 1;
+
+ if ( compulsory_break(*cp2) )
+ hard_break = 1;
+ else
+ hard_break = 0;
+
/* Back up if this isn't a breakpoint. */
{
unsigned w = cp2 - cp;
- if (*cp2)
- for (cp2--; !char_is_break (quote, (unsigned char) *cp2) && cp2 > cp;
+ if (*cp2 && ! compulsory_break(*cp2) )
+ for (cp2--; !char_is_break (quote, (unsigned char) *cp2) &&
+ cp2 > cp;
cp2--)
+ {
+
if (*cp2 == '"')
quote ^= 1;
+ }
if (w == width - indent
&& (unsigned) (cp2 - cp) <= (width - indent) * BREAK_LONG_WORD)
- for (; (unsigned) (cp2 - cp) < width - indent && *cp2; cp2++)
+ for (; (unsigned) (cp2 - cp) < width - indent && *cp2 ; cp2++)
if (*cp2 == '"')
quote ^= 1;
}
+
/* Write out the line. */
+
memset (buf, ' ', indent);
memcpy (&buf[indent], cp, cp2 - cp);
- buf[indent + cp2 - cp] = '\0';
- func (buf);
+ buf[indent + idx + cp2 - cp] = '\0';
+ func (buf);
cp = cp2;
}
local_free (buf);
}
-#if __CHECKER__
-/* Causes a segfault in order to force Checker to print a stack
- backtrace. */
-static void
-induce_segfault (void)
+
+void
+request_bug_report_and_abort(const char *msg )
{
- fputs (_("\n"
- "\t*********************\n"
- "\t* INDUCING SEGFAULT *\n"
- "\t*********************\n"), stdout);
- fflush (stdout);
- fflush (stderr);
- abort ();
-}
+ fprintf(stderr,
+ "******************************************************************\n"
+ "You have discovered a bug in PSPP.\n\n"
+ " Please report this, by sending "
+ "an email to " PACKAGE_BUGREPORT ",\n"
+ "explaining what you were doing when this happened, and including\n"
+ "a sample of your input file which caused it.\n");
+
+ fprintf(stderr,
+ "Also, please copy the following lines into your bug report:\n\n"
+ "bare_version: %s\n"
+ "version: %s\n"
+ "stat_version: %s\n"
+ "host_system: %s\n"
+ "build_system: %s\n"
+ "default_config_path: %s\n"
+ "include_path: %s\n"
+ "groff_font_path: %s\n"
+ "locale_dir: %s\n"
+ "compiler version: %s\n"
+ ,
+
+ bare_version,
+ version,
+ stat_version,
+ host_system,
+ build_system,
+ default_config_path,
+ include_path,
+ groff_font_path,
+ locale_dir,
+#ifdef __VERSION__
+ __VERSION__
+#else
+ "Unknown"
#endif
+ );
+
+ if ( msg )
+ fprintf(stderr,"Diagnosis: %s\n",msg);
+
+ fprintf(stderr,
+ "******************************************************************\n");
+
+ abort();
+}
+
+void
+err_assert_fail(const char *expr, const char *file, int line)
+{
+ char msg[256];
+ snprintf(msg,256,"Assertion failed: %s:%d; (%s)",file,line,expr);
+ request_bug_report_and_abort( msg );
+}