guards.cpp

Go to the documentation of this file.
00001 #ifndef GUARDS_IMPLEMENTATION_FILE
00002 #define GUARDS_IMPLEMENTATION_FILE
00003 
00004 /*****************************************************************************\
00005 *                                                                             *
00006 *  Name   : guards                                                            *
00007 *  Author : Chris Koeritz                                                     *
00008 *                                                                             *
00009 *******************************************************************************
00010 * Copyright (c) 1989-$now By Author.  This program is free software; you can  *
00011 * redistribute it and/or modify it under the terms of the GNU General Public  *
00012 * License as published by the Free Software Foundation; either version 2 of   *
00013 * the License or (at your option) any later version.  This is online at:      *
00014 *     http://www.fsf.org/copyleft/gpl.html                                    *
00015 * Please send any updates to: fred@gruntose.com                               *
00016 \*****************************************************************************/
00017 
00018 #include "function.h"
00019 #include "guards.h"
00020 #include "istring.h"
00021 #include "log_base.h"
00022 #include "portable.h"
00023 #include "utility.h"
00024 
00025 #include <errno.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028 
00029 #include <stdio.h>
00030 
00031 namespace guards {
00032 
00033 const int MESSAGE_SPACE_PROVIDED = 4096;
00034   // the strings should not be larger than this for diagnostic / error messages.
00035 //hmmm: how about we enforce that...???
00036 
00037 void write_to_console(const char *guards_message_space)
00038 { fprintf(stderr, guards_message_space); fflush(stderr); }
00039 
00040 void alert_message(const char *info, const char *title)
00041 {
00042   istring to_print;
00043   if (strlen(title)) {
00044     const char border = '=';
00045     to_print += istring(border, int(strlen(title)) + 4);
00046     to_print += log_base::platform_ending();
00047     to_print += border;
00048     to_print += ' ';
00049     to_print += title;
00050     to_print += ' ';
00051     to_print += border;
00052     to_print += log_base::platform_ending();
00053     to_print += istring(border, int(strlen(title)) + 4);
00054     to_print += log_base::platform_ending();
00055   }
00056 
00057   to_print += info;
00058   program_wide_logger().log(to_print);
00059   fflush(NIL);  // flush all output streams.
00060 }
00061 
00062 void alert_message(const istring &info) { alert_message(info.s()); }
00063 
00064 void alert_message(const istring &info, const istring &title)
00065 { alert_message(info.s(), title.s()); }
00066 
00067 void make_error_message(const char *file, int line,
00068     const char *error_class, const char *error_function,
00069     const char *info, char *guards_message_space)
00070 {
00071   strcpy(guards_message_space, "\nProblem reported for \"");
00072 //hmmm: only copy N chars of each into the space.
00073 //      say 40 for class/function each, then the space - consumed for the
00074 //      info.  get strlen for real on the class and function name to know
00075 //      actual size for that computation.
00076   strcat(guards_message_space, error_class);
00077   strcat(guards_message_space, "::");
00078   strcat(guards_message_space, error_function);
00079   strcat(guards_message_space, "\"\n(invoked at line ");
00080   char line_num[20];
00081   sprintf(line_num, "%d", line);
00082   strcat(guards_message_space, line_num);
00083   strcat(guards_message_space, " in ");
00084   strcat(guards_message_space, file);
00085   strcat(guards_message_space, " at ");
00086   strcat(guards_message_space, utility::timestamp(false, true).s());
00087   strcat(guards_message_space, ")\n");
00088   strcat(guards_message_space, info);
00089   strcat(guards_message_space, "\n\n\n");
00090 }
00091 
00092 void FL_deadly_error(const char *file, int line, const char *error_class,
00093     const char *error_function, const char *info)
00094 {
00095   FL_continuable_error(file, line, error_class, error_function, info,
00096       "Deadly Error Information");
00097   CAUSE_BREAKPOINT;
00098   throw "deadly_error";
00099     // abort() is not as good an approach as throwing an exception.  aborts are
00100     // harder to track with some compilers, but all should be able to trap an
00101     // exception.
00102 }
00103 
00104 void FL_deadly_error(const istring &file, int line,
00105     const istring &error_class, const istring &error_function,
00106     const istring &info)
00107 {
00108   FL_deadly_error(file.s(), line, error_class.s(), error_function.s(),
00109       info.s()); 
00110 }
00111 
00112 void FL_continuable_error_real(const char *file, int line,
00113     const char *error_class, const char *error_function, const char *info,
00114     const char *title)
00115 {
00116   char guards_message_space[MESSAGE_SPACE_PROVIDED];
00117     // this routine could still fail, if the call stack is already jammed
00118     // against its barrier.  but if that's the case, even the simple function
00119     // call might fail.  in any case, we cannot deal with a stack overflow
00120     // type error using this function.  but we would rather deal with that
00121     // than make the space static since that would cause corruption when
00122     // two threads wrote errors at the same time.
00123   make_error_message(file, line, error_class, error_function, info,
00124       guards_message_space);
00125   alert_message(guards_message_space, title);
00126 }
00127 
00128 void FL_continuable_error(const char *file, int line,
00129     const char *error_class, const char *error_function, const char *info,
00130     const char *title)
00131 {
00132   FL_continuable_error_real(file, line, error_class, error_function, info,
00133       title);
00134 }
00135 
00136 void FL_continuable_error(const istring &file, int line,
00137     const istring &error_class, const istring &error_function,
00138     const istring &info, const istring &title)
00139 {
00140   FL_continuable_error_real(file.s(), line, error_class.s(),
00141       error_function.s(), info.s(), title.s());
00142 }
00143 
00144 void FL_non_continuable_error(const char *file, int line,
00145     const char *error_class, const char *error_function, const char *info,
00146     const char *title)
00147 {
00148   FL_continuable_error_real(file, line, error_class, error_function, info,
00149       title);
00150   exit(EXIT_FAILURE);  // let the outside world know that there was a problem.
00151 }
00152 
00153 void FL_non_continuable_error(const istring &file, int line,
00154     const istring &error_class, const istring &error_function,
00155     const istring &info, const istring &title)
00156 {
00157   FL_continuable_error_real(file.s(), line, error_class.s(),
00158       error_function.s(), info.s(), title.s());
00159   exit(EXIT_FAILURE);  // let the outside world know that there was a problem.
00160 }
00161 
00162 void FL_console_error(const char *file, int line, const char *error_class,
00163     const char *error_function, const char *info)
00164 {
00165   char guards_message_space[MESSAGE_SPACE_PROVIDED];
00166   make_error_message(file, line, error_class, error_function, info,
00167       guards_message_space);
00168   write_to_console(guards_message_space);
00169 }
00170 
00171 void FL_out_of_memory_now(const char *file, int line,
00172     const char *the_class_name, const char *the_func)
00173 {
00174   FL_non_continuable_error(file, line, the_class_name, the_func, 
00175       "Program stopped due to memory allocation failure.",
00176       "Out of Memory Now");
00177 }
00178 
00179 void implement_bounds_halt(const char *the_class_name, const char *the_func,
00180     const char *value, const char *low, const char *high,
00181     const char *error_addition)
00182 {
00183   char message[400];
00184   strcpy(message, "bounds error caught");
00185   strcat(message, error_addition);
00186   strcat(message, ":\r\n");
00187   strcat(message, value);
00188   strcat(message, " is not between ");
00189   strcat(message, low);
00190   strcat(message, " and ");
00191   strcat(message, high);
00192 #ifdef ERRORS_ARE_FATAL
00193   deadly_error(the_class_name, the_func, message);
00194 #else
00195   continuable_error(the_class_name, the_func, message);
00196 #endif
00197 }
00198 
00199 } // namespace
00200 
00201 
00202 #endif //GUARDS_IMPLEMENTATION_FILE
00203 

Generated on Fri Nov 28 04:29:07 2008 for HOOPLE Libraries by  doxygen 1.5.1