Drizzled Public API Documentation

error_message.cc
00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 Sun Microsystems, Inc.
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; version 2 of the License.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018  */
00019 
00020 #include <config.h>
00021 
00022 #include <drizzled/error.h>
00023 #include <drizzled/gettext.h>
00024 #include <drizzled/plugin/error_message.h>
00025 
00026 #include <cstdio>
00027 #include <algorithm>
00028 #include <vector>
00029 
00030 namespace drizzled
00031 {
00032 
00033 std::vector<plugin::ErrorMessage *> all_errmsg_handler;
00034 
00035 bool plugin::ErrorMessage::addPlugin(plugin::ErrorMessage *handler)
00036 {
00037   all_errmsg_handler.push_back(handler);
00038   return false;
00039 }
00040 
00041 void plugin::ErrorMessage::removePlugin(plugin::ErrorMessage *)
00042 {
00043   all_errmsg_handler.clear();
00044 }
00045 
00046 
00047 class Print : public std::unary_function<plugin::ErrorMessage *, bool>
00048 {
00049   error::priority_t priority;
00050   const char *format;
00051   va_list ap;
00052 
00053 public:
00054   Print(error::priority_t priority_arg,
00055         const char *format_arg, va_list ap_arg) : 
00056     std::unary_function<plugin::ErrorMessage *, bool>(),
00057     priority(priority_arg), format(format_arg)
00058   {
00059     va_copy(ap, ap_arg);
00060   }
00061 
00062   ~Print()  { va_end(ap); }
00063 
00064   inline result_type operator()(argument_type handler)
00065   {
00066     va_list handler_ap;
00067     va_copy(handler_ap, ap);
00068     if (handler->errmsg(priority, format, handler_ap))
00069     {
00070       /* we're doing the errmsg plugin api,
00071          so we can't trust the errmsg api to emit our error messages
00072          so we will emit error messages to stderr */
00073       /* TRANSLATORS: The leading word "errmsg" is the name
00074          of the plugin api, and so should not be translated. */
00075       fprintf(stderr,
00076               _("errmsg plugin '%s' errmsg() failed"),
00077               handler->getName().c_str());
00078       va_end(handler_ap);
00079 
00080       return true;
00081     }
00082     va_end(handler_ap);
00083     return false;
00084   }
00085 }; 
00086 
00087 
00088 bool plugin::ErrorMessage::vprintf(error::priority_t priority, char const *format, va_list ap)
00089 {
00090   if (priority > error::verbosity())
00091   {
00092     return false;
00093   }
00094 
00095   /* 
00096     Check to see if any errmsg plugin has been loaded
00097     if not, just fall back to emitting the message to stderr.
00098   */
00099   if (all_errmsg_handler.size() == 0)
00100   {
00101     /* if it turns out that the vfprintf doesnt do one single write
00102       (single writes are atomic), then this needs to be rewritten to
00103       vsprintf into a char buffer, and then write() that char buffer
00104       to stderr 
00105     */
00106     vfprintf(stderr, format, ap);
00107     fputc('\n', stderr);
00108 
00109     return false;
00110   }
00111 
00112   /* Use find_if instead of foreach so that we can collect return codes */
00113   std::vector<plugin::ErrorMessage *>::iterator iter=
00114     std::find_if(all_errmsg_handler.begin(), all_errmsg_handler.end(),
00115                  Print(priority, format, ap)); 
00116 
00117   /* If iter is == end() here, that means that all of the plugins returned
00118    * false, which in this case means they all succeeded. Since we want to 
00119    * return false on success, we return the value of the two being != 
00120    */
00121   return iter != all_errmsg_handler.end();
00122 }
00123 
00124 } /* namespace drizzled */