Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, 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 "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
msg (int class, const char *format, ...)
{
- char buf[1024];
+ struct string buf;
+ ds_init (NULL, &buf, 1024);
+
/* Format the message into BUF. */
{
va_list args;
va_start (args, format);
- vsnprintf (buf, 1024, format, args);
+ ds_vprintf (&buf, format, args);
va_end (args);
}
e.class = class;
err_location (&e.where);
e.title = NULL;
- e.text = buf;
+ e.text = buf.string;
err_vmsg (&e);
}
+
+ ds_destroy (&buf);
}
/* 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
outp_done ();
-#if __CHECKER__
- if (!success)
- induce_segfault ();
-#endif
-
exit (success ? EXIT_SUCCESS : EXIT_FAILURE);
}
/* 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 */
};
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_value (&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);
+ if ( hard_break)
+ {
+ buf[indent + idx + cp2 - cp] = '\n';
+ ++idx;
+ }
+ 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",
+
+ bare_version,
+ version,
+ stat_version,
+ host_system,
+ build_system,
+ default_config_path,
+ include_path,
+ groff_font_path,
+ locale_dir);
+
+ 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 );
}
-#endif