X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ferror.c;h=3a77c8722217868ac07e212df8c5aaaa83efd69e;hb=92fb12eb06716d14c05b781f5d9dcde956d77c30;hp=1983df4d056b92ec412f9a6c25f11948dfb1b9a0;hpb=4944c86a9318bc5b5578ab145a95c116ffd2c9fd;p=pspp diff --git a/src/error.c b/src/error.c index 1983df4d05..3a77c87222 100644 --- a/src/error.c +++ b/src/error.c @@ -14,41 +14,32 @@ 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 -#if __GNUC__ -#define alloca __builtin_alloca -#else -#if HAVE_ALLOCA_H -#include -#else -#ifdef _AIX -#pragma alloca -#else -#ifndef alloca /* predefined by HP cc +Olibcalls */ -char *alloca (); -#endif -#endif -#endif -#endif - -#include +#include "error.h" #include #include #include #include #include "alloc.h" #include "command.h" -#include "error.h" -#include "getline.h" +#include "getl.h" +#include "glob.h" +#include "lexer.h" #include "main.h" #include "output.h" +#include "progname.h" +#include "readln.h" #include "settings.h" #include "str.h" #include "var.h" +#include "version.h" + +#include "gettext.h" +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid int err_error_count; int err_warning_count; @@ -57,9 +48,6 @@ int err_already_flagged; int err_verbosity; -/* File locator stack. */ -static const struct file_locator **file_loc; -static int nfile_loc, mfile_loc; /* Fairly common public functions. */ @@ -68,27 +56,16 @@ static int nfile_loc, mfile_loc; 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 @@ -96,27 +73,16 @@ tmsg (int class, const char *title, const char *format, ...) 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. */ @@ -126,10 +92,10 @@ err_failure (void) fflush (stdout); fflush (stderr); - fprintf (stderr, "%s: %s\n", pgmname, + fprintf (stderr, "%s: %s\n", program_name, _("Terminating NOW due to a fatal error!")); - err_hcf (0); + terminate (false); } /* Terminate unless we're interactive or will go interactive when the @@ -137,7 +103,7 @@ err_failure (void) void err_cond_fail (void) { - if (getl_reading_script) + if (getl_reading_script ()) { if (getl_interactive) getl_close_all (); @@ -146,46 +112,6 @@ err_cond_fail (void) } } -/* File locator stack functions. */ - -/* Pushes F onto the stack of file locations. */ -void -err_push_file_locator (const struct file_locator *f) -{ - if (nfile_loc >= mfile_loc) - { - if (mfile_loc == 0) - mfile_loc = 8; - else - mfile_loc *= 2; - - file_loc = xrealloc (file_loc, mfile_loc * sizeof *file_loc); - } - - file_loc[nfile_loc++] = f; -} - -/* Pops F off the stack of file locations. - Argument F is only used for verification that that is actually the - item on top of the stack. */ -void -err_pop_file_locator (const struct file_locator *f) -{ - assert (nfile_loc >= 0 && file_loc[nfile_loc - 1] == f); - nfile_loc--; -} - -/* Puts the current file and line number in F, or NULL and -1 if - none. */ -void -err_location (struct file_locator *f) -{ - if (nfile_loc) - *f = *file_loc[nfile_loc - 1]; - else - getl_location (&f->filename, &f->line_number); -} - /* Obscure public functions. */ /* Writes a blank line to the error device(s). @@ -203,24 +129,20 @@ err_check_count (void) { 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 @@ -230,34 +152,20 @@ static void induce_segfault (void); #define EXIT_FAILURE 1 #endif -static int terminating; +static void puts_stdout (const char *s); +static void dump_message (char *errbuf, unsigned indent, + void (*func) (const char *), unsigned width); -/* Halt-catch-fire. SUCCESS should be nonzero if exiting successfully - or zero if not. Despite the name, this is the usual way to finish, - successfully or not. */ void -err_hcf (int success) +err_done (void) { - terminating = 1; - + lex_done(); getl_uninitialize (); - - outp_done (); - -#if __CHECKER__ - if (!success) - induce_segfault (); -#endif - - exit (success ? EXIT_SUCCESS : EXIT_FAILURE); + readln_uninitialize(); } -static void puts_stdout (const char *s); -static void dump_message (char *errbuf, unsigned indent, - 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 @@ -269,7 +177,7 @@ err_vmsg (const struct error *e) /* 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. */ }; @@ -285,11 +193,11 @@ err_vmsg (const struct error *e) {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 */ }; @@ -303,15 +211,15 @@ err_vmsg (const struct error *e) 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)); @@ -326,9 +234,9 @@ err_vmsg (const struct error *e) 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. @@ -336,12 +244,12 @@ err_vmsg (const struct error *e) 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); - if (e->class == FE && !terminating) - err_hcf (0); + if (e->class == FE) + terminate (0); } /* Private functions. */ @@ -363,13 +271,20 @@ puts_stdout (const char *s) 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 @@ -425,12 +340,13 @@ dump_message (char *msg, unsigned indent, void (*func) (const char *), 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; @@ -456,62 +372,127 @@ dump_message (char *msg, unsigned indent, void (*func) (const char *), *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 ); +}