]> Dogcows Code - chaz/yoink/blobdiff - src/stlplus/subsystems/message_handler.cpp
testing new non-autotools build system
[chaz/yoink] / src / stlplus / subsystems / message_handler.cpp
diff --git a/src/stlplus/subsystems/message_handler.cpp b/src/stlplus/subsystems/message_handler.cpp
new file mode 100644 (file)
index 0000000..fd1d2e8
--- /dev/null
@@ -0,0 +1,2014 @@
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+//   Author:    Andy Rushton\r
+//   Copyright: (c) Southampton University 1999-2004\r
+//              (c) Andy Rushton           2004-2009\r
+//   License:   BSD License, see ../docs/license.html\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+#include "message_handler.hpp"\r
+#include "dprintf.hpp"\r
+#include <fstream>\r
+#include <map>\r
+#include <list>\r
+#include <ctype.h>\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+namespace stlplus\r
+{\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // Utilities\r
+\r
+  static std::ostream& operator<< (std::ostream& device, const std::vector<std::string>& data)\r
+  {\r
+    for (unsigned i = 0; i < data.size(); i++)\r
+      device << data[i] << std::endl;\r
+    device.flush();\r
+    return device;\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+\r
+  static const char* information_id = "INFORMATION";\r
+  static const char* context_id = "CONTEXT";\r
+  static const char* supplement_id = "SUPPLEMENT";\r
+  static const char* warning_id = "WARNING";\r
+  static const char* error_id = "ERROR";\r
+  static const char* fatal_id = "FATAL";\r
+  static const char* position_id = "POSITION";\r
+\r
+  static const char* default_information_format = "@0";\r
+  static const char* default_context_format = "context: @0";\r
+  static const char* default_supplement_format = "supplement: @0";\r
+  static const char* default_warning_format = "warning: @0";\r
+  static const char* default_error_format = "error: @0";\r
+  static const char* default_fatal_format = "FATAL: @0";\r
+  static const char* default_position_format = "\"@1\" (@2,@3) : @0";\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // position class\r
+\r
+  message_position::message_position(void) :\r
+    m_filename(std::string()), m_line(0), m_column(0) \r
+  {\r
+  }\r
+\r
+  message_position::message_position(const std::string& filename, unsigned line, unsigned column) :\r
+    m_filename(filename), m_line(line), m_column(column)\r
+  {\r
+  }\r
+\r
+  message_position::~message_position(void)\r
+  {\r
+  }\r
+\r
+  const std::string& message_position::filename(void) const\r
+  {\r
+    return m_filename;\r
+  }\r
+\r
+  unsigned message_position::line(void) const\r
+  {\r
+    return m_line;\r
+  }\r
+\r
+  unsigned message_position::column(void) const\r
+  {\r
+    return m_column;\r
+  }\r
+\r
+  message_position message_position::operator + (unsigned offset) const\r
+  {\r
+    message_position result(*this);\r
+    result += offset;\r
+    return result;\r
+  }\r
+\r
+  message_position& message_position::operator += (unsigned offset)\r
+  {\r
+    m_column += offset;\r
+    return *this;\r
+  }\r
+\r
+  bool message_position::empty(void) const\r
+  {\r
+    return m_filename.empty();\r
+  }\r
+\r
+  bool message_position::valid(void) const\r
+  {\r
+    return !empty();\r
+  }\r
+\r
+  std::vector<std::string> message_position::show(void) const\r
+  {\r
+    std::vector<std::string> result;\r
+    if (valid())\r
+    {\r
+      // skip row-1 lines of the file and print out the resultant line\r
+      std::ifstream source(filename().c_str());\r
+      std::string current_line;\r
+      for (unsigned i = 0; i < line(); i++)\r
+      {\r
+        if (!source.good())\r
+          return result;\r
+        std::getline(source,current_line);\r
+      }\r
+      result.push_back(current_line);\r
+      // now put an up-arrow at the appropriate column\r
+      // preserve any tabs in the original line\r
+      result.push_back(std::string());\r
+      for (unsigned j = 0; j < column(); j++)\r
+      {\r
+        if (j < current_line.size() && current_line[j] == '\t')\r
+          result.back() += '\t';\r
+        else\r
+          result.back() += ' ';\r
+      }\r
+      result.back() += '^';\r
+    }\r
+    return result;\r
+  }\r
+\r
+  std::string to_string(const message_position& where)\r
+  {\r
+    return dformat("{%s:%u:%u}", where.filename().c_str(), where.line(), where.column());\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // context subclass\r
+\r
+  class message_context_body\r
+  {\r
+  private:\r
+    unsigned m_depth;\r
+    message_handler_base* m_base;\r
+\r
+  public:\r
+    message_context_body(message_handler_base& handler) :\r
+      m_depth(0), m_base(0)\r
+      {\r
+        set(handler);\r
+      }\r
+\r
+    ~message_context_body(void)\r
+      {\r
+        pop();\r
+      }\r
+\r
+    void set(message_handler_base& handler)\r
+      {\r
+        m_base = &handler;\r
+        m_depth = m_base->context_depth();\r
+      }\r
+\r
+    void pop(void)\r
+      {\r
+        if (m_base)\r
+          m_base->pop_context(m_depth);\r
+      }\r
+  private:\r
+    message_context_body(const message_context_body&);\r
+    message_context_body& operator=(const message_context_body&);\r
+  };\r
+\r
+  // exported context class\r
+\r
+  message_context::message_context(message_handler_base& handler) : m_body(new message_context_body(handler))\r
+  {\r
+  }\r
+\r
+  void message_context::set(message_handler_base& handler)\r
+  {\r
+    m_body->set(handler);\r
+  }\r
+\r
+  void message_context::pop(void)\r
+  {\r
+    m_body->pop();\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // exceptions\r
+\r
+  // read_error\r
+\r
+  message_handler_read_error::message_handler_read_error(const message_position& position, const std::string& reason) :\r
+    std::runtime_error(to_string(position) + std::string(": Message handler read error - ") + reason), \r
+    m_position(position)\r
+  {\r
+  }\r
+\r
+  message_handler_read_error::~message_handler_read_error(void) throw()\r
+  {\r
+  }\r
+\r
+  const message_position& message_handler_read_error::where(void) const\r
+  {\r
+    return m_position;\r
+  }\r
+\r
+  // format error\r
+\r
+  message_handler_format_error::message_handler_format_error(const std::string& format, unsigned offset) :\r
+    std::runtime_error(std::string("Message handler formatting error in \"") + format + std::string("\"")),\r
+    m_position("",0,0), m_format(format), m_offset(offset)\r
+  {\r
+  }\r
+\r
+  message_handler_format_error::message_handler_format_error(const message_position& pos, const std::string& format, unsigned offset) : \r
+    std::runtime_error(to_string(pos) + std::string(": Message handler formatting error in \"") + format + std::string("\"")), \r
+    m_position(pos), m_format(format), m_offset(offset)\r
+  {\r
+  }\r
+\r
+  message_handler_format_error::~message_handler_format_error(void) throw()\r
+  {\r
+  }\r
+\r
+  const message_position& message_handler_format_error::where(void) const\r
+  {\r
+    return m_position;\r
+  }\r
+\r
+  const std::string& message_handler_format_error::format(void) const\r
+  {\r
+    return m_format;\r
+  }\r
+\r
+  unsigned message_handler_format_error::offset(void) const\r
+  {\r
+    return m_offset;\r
+  }\r
+\r
+  // id_error\r
+\r
+  message_handler_id_error::message_handler_id_error(const std::string& id) :\r
+    std::runtime_error(std::string("Message handler message ID not found: ") + id), m_id(id)\r
+  {\r
+  }\r
+\r
+  message_handler_id_error::~message_handler_id_error(void) throw()\r
+  {\r
+  }\r
+\r
+  const std::string& message_handler_id_error::id(void) const\r
+  {\r
+    return m_id;\r
+  }\r
+\r
+  // limit_error\r
+\r
+  message_handler_limit_error::message_handler_limit_error(unsigned limit) : \r
+    std::runtime_error(std::string("Message handler limit error: ") + dformat("%u",limit) + std::string(" reached")),\r
+    m_limit(limit)\r
+  {\r
+  }\r
+\r
+  message_handler_limit_error::~message_handler_limit_error(void) throw()\r
+  {\r
+  }\r
+\r
+  unsigned message_handler_limit_error::limit(void) const\r
+  {\r
+    return m_limit;\r
+  }\r
+\r
+  // fatal_error\r
+\r
+  message_handler_fatal_error::message_handler_fatal_error(const std::string& id) : \r
+    std::runtime_error(std::string("Message Handler Fatal error: ") + id),\r
+    m_id(id)\r
+  {\r
+  }\r
+\r
+  message_handler_fatal_error::~message_handler_fatal_error(void) throw()\r
+  {\r
+  }\r
+\r
+  const std::string& message_handler_fatal_error::id(void) const\r
+  {\r
+    return m_id;\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+\r
+  class message\r
+  {\r
+  private:\r
+    unsigned m_index;    // index into message files\r
+    unsigned m_line;     // line\r
+    unsigned m_column;   // column\r
+    std::string m_text;  // text\r
+\r
+  public:\r
+    message(unsigned index = (unsigned)-1,\r
+            unsigned line = 0,\r
+            unsigned column = 0,\r
+            const std::string& text = "") :\r
+      m_index(index),m_line(line),m_column(column),m_text(text)\r
+      {\r
+      }\r
+    message(const std::string& text) :\r
+      m_index((unsigned)-1),m_line(0),m_column(0),m_text(text)\r
+      {\r
+      }\r
+\r
+    ~message(void)\r
+      {\r
+      }\r
+\r
+    unsigned index(void) const\r
+      {\r
+        return m_index;\r
+      }\r
+\r
+    unsigned line(void) const\r
+      {\r
+        return m_line;\r
+      }\r
+\r
+    unsigned column(void) const\r
+      {\r
+        return m_column;\r
+      }\r
+\r
+    const std::string& text(void) const\r
+      {\r
+        return m_text;\r
+      }\r
+  };\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+\r
+  class pending_message\r
+  {\r
+  private:\r
+    message_position m_position;\r
+    std::string m_id;\r
+    std::vector<std::string> m_args;\r
+  public:\r
+    pending_message(const message_position& position, const std::string& id, const std::vector<std::string>& args) :\r
+      m_position(position), m_id(id), m_args(args) {}\r
+    pending_message(const std::string& id, const std::vector<std::string>& args) :\r
+      m_position(message_position()), m_id(id), m_args(args) {}\r
+    ~pending_message(void) {}\r
+\r
+    const message_position& position(void) const {return m_position;}\r
+    const std::string& id(void) const {return m_id;}\r
+    const std::vector<std::string>& args(void) const {return m_args;}\r
+  };\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+\r
+  class message_handler_base_body\r
+  {\r
+  public:\r
+    std::vector<std::string> m_files;          // message files in the order they were added\r
+    std::map<std::string,message> m_messages;  // messages stored as id:message pairs\r
+    bool m_show;                               // show source\r
+    std::list<pending_message> m_context;      // context message stack\r
+    std::list<pending_message> m_supplement;   // supplementary message stack\r
+\r
+  public:\r
+    message_handler_base_body(void) :\r
+      m_show(false)\r
+      {\r
+        // preload with default formats\r
+        add_message(information_id,default_information_format);\r
+        add_message(warning_id,default_warning_format);\r
+        add_message(error_id,default_error_format);\r
+        add_message(fatal_id,default_fatal_format);\r
+        add_message(position_id,default_position_format);\r
+        add_message(context_id,default_context_format);\r
+        add_message(supplement_id,default_supplement_format);\r
+      }\r
+\r
+    ~message_handler_base_body(void)\r
+      {\r
+      }\r
+\r
+    void set_show(bool show)\r
+      {\r
+        m_show = show;\r
+      }\r
+\r
+    void add_message_file(const std::string& file)\r
+      throw(message_handler_read_error)\r
+      {\r
+        m_files.push_back(file);\r
+        std::ifstream input(file.c_str());\r
+        if (!input.good()) \r
+          throw message_handler_read_error(message_position(file,0,0), std::string("file not found: ") + file);\r
+        std::string line;\r
+        unsigned l = 0;\r
+        while(input.good())\r
+        {\r
+          std::getline(input,line);\r
+          l++;\r
+          if (line.size() > 0 && isalpha(line[0]))\r
+          {\r
+            // Get the id field which starts with an alphabetic and contains alphanumerics and underscore\r
+            std::string id;\r
+            unsigned i = 0;\r
+            for (; i < line.size(); i++)\r
+            {\r
+              if (isalnum(line[i]) || line[i] == '_')\r
+                id += line[i];\r
+              else\r
+                break;\r
+            }\r
+            // check this ID is unique within the files - however it is legal to override a hard-coded message\r
+            std::map<std::string,message>::iterator found = m_messages.find(id);\r
+            if (found != m_messages.end() && found->second.index() != (unsigned)-1)\r
+              throw message_handler_read_error(message_position(file,l,i), std::string("repeated ID ") + id);\r
+            // skip whitespace\r
+            for (; i < line.size(); i++)\r
+            {\r
+              if (!isspace(line[i]))\r
+                break;\r
+            }\r
+            // now get the text part and add the message to the message map\r
+            std::string text = line.substr(i, line.size()-i);\r
+            m_messages[id] = message(m_files.size()-1, l, i, text);\r
+          }\r
+        }\r
+      }\r
+\r
+    void add_message(const std::string& id, const std::string& text)\r
+      throw()\r
+      {\r
+        m_messages[id] = message((unsigned)-1, 0, 0, text);\r
+      }\r
+\r
+    bool message_present(const std::string& id) const\r
+      throw()\r
+      {\r
+        return m_messages.find(id) != m_messages.end();\r
+      }\r
+\r
+    void push_supplement(const message_position& position,\r
+                         const std::string& message_id,\r
+                         const std::vector<std::string>& args)\r
+      {\r
+        m_supplement.push_back(pending_message(position,message_id,args));\r
+      }\r
+\r
+    void push_context(const message_position& position,\r
+                      const std::string& message_id,\r
+                      const std::vector<std::string>& args)\r
+      {\r
+        m_context.push_back(pending_message(position,message_id,args));\r
+      }\r
+\r
+    void pop_context(unsigned depth)\r
+      {\r
+        while (depth < m_context.size())\r
+          m_context.pop_back();\r
+      }\r
+\r
+    unsigned context_depth(void) const\r
+      {\r
+        return m_context.size();\r
+      }\r
+\r
+    std::vector<std::string> format_report(const message_position& position,\r
+                                           const std::string& message_id,\r
+                                           const std::string& status_id,\r
+                                           const std::vector<std::string>& args)\r
+      throw(message_handler_id_error,message_handler_format_error)\r
+      {\r
+        // gathers everything together into a full multi-line report\r
+        std::vector<std::string> result;\r
+        // the first part of the report is the status message (info/warning/error/fatal)\r
+        result.push_back(format_id(position, message_id, status_id, args));\r
+        // now append any supplemental messages that have been stacked\r
+        // these are printed in FIFO order i.e. the order that they were added to the handler\r
+        for (std::list<pending_message>::iterator j = m_supplement.begin(); j != m_supplement.end(); j++)\r
+          result.push_back(format_id(j->position(),j->id(),supplement_id,j->args()));\r
+        // now discard any supplementary messages because they only persist until they are printed once\r
+        m_supplement.clear();\r
+        // now append any context messages that have been stacked\r
+        // these are printed in LIFO order i.e. closest context first\r
+        for (std::list<pending_message>::reverse_iterator i = m_context.rbegin(); i != m_context.rend(); i++)\r
+          result.push_back(format_id(i->position(),i->id(),context_id,i->args()));\r
+        return result;\r
+      }\r
+\r
+    std::string format_id(const message_position& position,\r
+                          const std::string& message_id,\r
+                          const std::string& status_id,\r
+                          const std::vector<std::string>& args)\r
+      throw(message_handler_id_error,message_handler_format_error)\r
+      {\r
+        // This function creates a fully-formatted single-line message from a\r
+        // combination of the position format and the status format plus the message\r
+        // ID and its arguments. There are up to three levels of substitution\r
+        // required to do this.\r
+\r
+        // get the status format from the status_id\r
+        std::map<std::string,message>::iterator status_found = m_messages.find(status_id);\r
+        if (status_found == m_messages.end()) throw message_handler_id_error(status_id);\r
+\r
+        // similarly get the message format\r
+        std::map<std::string,message>::iterator message_found = m_messages.find(message_id);\r
+        if (message_found == m_messages.end()) throw message_handler_id_error(message_id);\r
+\r
+        // format the message contents\r
+        std::string message_text = format_message(message_found->second, args);\r
+\r
+        // now format the message in the status string (informational, warning etc).\r
+        std::vector<std::string> status_args;\r
+        status_args.push_back(message_text);\r
+        std::string result = format_message(status_found->second, status_args);\r
+\r
+        // finally, if the message is positional, format the status message in the positional string\r
+        if (position.valid())\r
+        {\r
+          // get the position format from the message set\r
+          std::map<std::string,message>::iterator position_found = m_messages.find(position_id);\r
+          if (position_found == m_messages.end()) throw message_handler_id_error(position_id);\r
+\r
+          // now format the message\r
+          std::vector<std::string> position_args;\r
+          position_args.push_back(result);\r
+          position_args.push_back(position.filename());\r
+          position_args.push_back(dformat("%u",position.line()));\r
+          position_args.push_back(dformat("%u",position.column()));\r
+          result = format_message(position_found->second, position_args);\r
+          // add the source file text and position if that option is on\r
+\r
+          if (m_show)\r
+          {\r
+            std::vector<std::string> show = position.show();\r
+            for (unsigned i = 0; i < show.size(); i++)\r
+            {\r
+              result += std::string("\n");\r
+              result += show[i];\r
+            }\r
+          }\r
+        }\r
+        return result;\r
+      }\r
+\r
+    std::string format_message(const message& mess,\r
+                               const std::vector<std::string>& args) \r
+      throw(message_handler_format_error)\r
+      {\r
+        // this function creates a formatted string from the stored message text and\r
+        // the arguments. Most of the work is done in format_string. However, if a\r
+        // formatting error is found, this function uses extra information stored in\r
+        // the message data structure to improve the reporting of the error\r
+        try\r
+        {\r
+          // This is the basic string formatter which performs parameter substitution\r
+          // into a message. Parameter placeholders are in the form @0, @1 etc, where\r
+          // the number is the index of the argument in the args vector. At present,\r
+          // no field codes are supported as in printf formats Algorithm: scan the\r
+          // input string and transfer it into the result. When an @nnn appears,\r
+          // substitute the relevant argument from the args vector. Throw an exception\r
+          // if its out of range. Also convert C-style escaped characters of the form\r
+          // \n.\r
+          std::string format = mess.text();\r
+          std::string result;\r
+          for (unsigned i = 0; i < format.size(); )\r
+          {\r
+            if (format[i] == '@')\r
+            {\r
+              // an argument substitution has been found - now find the argument number\r
+              if (i+1 == format.size()) throw message_handler_format_error(format, i);\r
+              i++;\r
+              // check for @@ which is an escaped form of '@'\r
+              if (format[i] == '@')\r
+              {\r
+                result += '@';\r
+                i++;\r
+              }\r
+              else\r
+              {\r
+                // there must be at least one digit in the substitution number\r
+                if (!isdigit(format[i])) throw message_handler_format_error(format,i);\r
+                unsigned a = 0;\r
+                for (; i < format.size() && isdigit(format[i]); i++)\r
+                {\r
+                  a *= 10;\r
+                  a += (format[i] - '0');\r
+                }\r
+                // check for an argument request out of the range of the set of arguments\r
+                if (a >= args.size()) throw message_handler_format_error(format,i-1);\r
+                result += args[a];\r
+              }\r
+            }\r
+            else if (format[i] == '\\')\r
+            {\r
+              // an escaped character has been found\r
+              if (i+1 == format.size()) throw message_handler_format_error(format, i);\r
+              i++;\r
+              // do the special ones first, then all the others just strip off the \ and leave the following characters\r
+              switch(format[i])\r
+              {\r
+              case '\\':\r
+                result += '\\';\r
+                break;\r
+              case 't':\r
+                result += '\t';\r
+                break;\r
+              case 'n':\r
+                result += '\n';\r
+                break;\r
+              case 'r':\r
+                result += '\r';\r
+                break;\r
+              case 'a':\r
+                result += '\a';\r
+                break;\r
+              default:\r
+                result += format[i];\r
+                break;\r
+              }\r
+              i++;\r
+            }\r
+            else\r
+            {\r
+              // plain text found - just append to the result\r
+              result += format[i++];\r
+            }\r
+          }\r
+          return result;\r
+        }\r
+        catch(message_handler_format_error& exception)\r
+        {\r
+          // if the message came from a message file, improve the error reporting by adding file positional information\r
+          // Also adjust the position from the start of the text (stored in the message field) to the column of the error\r
+          if (mess.index() != (unsigned)-1)\r
+            throw message_handler_format_error(\r
+              message_position(m_files[mess.index()], mess.line(), mess.column()+exception.offset()),\r
+              exception.format(),\r
+              exception.offset());\r
+          else\r
+            throw exception;\r
+        }\r
+      }\r
+\r
+  private:\r
+    message_handler_base_body(message_handler_base_body&);\r
+    message_handler_base_body& operator=(message_handler_base_body&);\r
+  };\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+\r
+  message_handler_base::message_handler_base(bool show)\r
+    throw() :\r
+    m_base_body(new message_handler_base_body)\r
+  {\r
+    m_base_body->set_show(show);\r
+  }\r
+\r
+  message_handler_base::message_handler_base(const std::string& file, bool show)\r
+    throw(message_handler_read_error) :\r
+    m_base_body(new message_handler_base_body)\r
+  {\r
+    m_base_body->set_show(show);\r
+    add_message_file(file);\r
+  }\r
+\r
+  message_handler_base::message_handler_base(const std::vector<std::string>& files, bool show)\r
+    throw(message_handler_read_error) :\r
+    m_base_body(new message_handler_base_body)\r
+  {\r
+    m_base_body->set_show(show);\r
+    add_message_files(files);\r
+  }\r
+\r
+  message_handler_base::~message_handler_base(void)\r
+    throw()\r
+  {\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+\r
+  void message_handler_base::add_message_file(const std::string& file)\r
+    throw(message_handler_read_error)\r
+  {\r
+    m_base_body->add_message_file(file);\r
+  }\r
+\r
+  void message_handler_base::add_message_files(const std::vector<std::string>& files)\r
+    throw(message_handler_read_error)\r
+  {\r
+    for (unsigned i = 0; i < files.size(); i++)\r
+      add_message_file(files[i]);\r
+  }\r
+\r
+  void message_handler_base::add_message(const std::string& id, const std::string& text)\r
+    throw()\r
+  {\r
+    m_base_body->add_message(id,text);\r
+  }\r
+\r
+  bool message_handler_base::message_present(const std::string& id) const\r
+    throw()\r
+  {\r
+    return m_base_body->message_present(id);\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+\r
+  void message_handler_base::set_information_format(const std::string& format) throw()\r
+  {\r
+    add_message(information_id, format);\r
+  }\r
+\r
+  void message_handler_base::set_warning_format(const std::string& format) throw()\r
+  {\r
+    add_message(warning_id, format);\r
+  }\r
+\r
+  void message_handler_base::set_error_format(const std::string& format) throw()\r
+  {\r
+    add_message(error_id, format);\r
+  }\r
+\r
+  void message_handler_base::set_fatal_format(const std::string& format) throw()\r
+  {\r
+    add_message(fatal_id, format);\r
+  }\r
+\r
+  void message_handler_base::set_position_format(const std::string& format) throw()\r
+  {\r
+    add_message(position_id, format);\r
+  }\r
+\r
+  void message_handler_base::set_context_format(const std::string& format) throw()\r
+  {\r
+    add_message(context_id, format);\r
+  }\r
+\r
+  void message_handler_base::set_supplement_format(const std::string& format) throw()\r
+  {\r
+    add_message(supplement_id, format);\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+\r
+  void message_handler_base::show_position(void)\r
+    throw()\r
+  {\r
+    m_base_body->set_show(true);\r
+  }\r
+\r
+  void message_handler_base::hide_position(void)\r
+    throw()\r
+  {\r
+    m_base_body->set_show(false);\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // information messages\r
+\r
+  std::vector<std::string> message_handler_base::information_message(const std::string& id,\r
+                                                                     const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    return information_message(message_position(), id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::information_message(const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    return information_message(id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::information_message(const std::string& id,\r
+                                                                     const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    return information_message(id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::information_message(const std::string& id,\r
+                                                                     const std::string& arg1,\r
+                                                                     const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    return information_message(id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::information_message(const std::string& id,\r
+                                                                     const std::string& arg1,\r
+                                                                     const std::string& arg2,\r
+                                                                     const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    args.push_back(arg3);\r
+    return information_message(id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::information_message(const message_position& position,\r
+                                                                     const std::string& id,\r
+                                                                     const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    return m_base_body->format_report(position, id, information_id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::information_message(const message_position& position,\r
+                                                                     const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    return information_message(position, id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::information_message(const message_position& position,\r
+                                                                     const std::string& id,\r
+                                                                     const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    return information_message(position, id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::information_message(const message_position& position,\r
+                                                                     const std::string& id,\r
+                                                                     const std::string& arg1,\r
+                                                                     const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    return information_message(position, id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::information_message(const message_position& position,\r
+                                                                     const std::string& id,\r
+                                                                     const std::string& arg1,\r
+                                                                     const std::string& arg2,\r
+                                                                     const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    args.push_back(arg3);\r
+    return information_message(position, id, args);\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // warning messages\r
+\r
+  std::vector<std::string> message_handler_base::warning_message(const std::string& id,\r
+                                                                 const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    return warning_message(message_position(), id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::warning_message(const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    return warning_message(id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::warning_message(const std::string& id,\r
+                                                                 const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    return warning_message(id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::warning_message(const std::string& id,\r
+                                                                 const std::string& arg1,\r
+                                                                 const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    return warning_message(id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::warning_message(const std::string& id,\r
+                                                                 const std::string& arg1,\r
+                                                                 const std::string& arg2,\r
+                                                                 const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    args.push_back(arg3);\r
+    return warning_message(id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::warning_message(const message_position& position,\r
+                                                                 const std::string& id,\r
+                                                                 const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    return m_base_body->format_report(position, id, warning_id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::warning_message(const message_position& position,\r
+                                                                 const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    return warning_message(position, id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::warning_message(const message_position& position,\r
+                                                                 const std::string& id,\r
+                                                                 const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    return warning_message(position, id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::warning_message(const message_position& position,\r
+                                                                 const std::string& id,\r
+                                                                 const std::string& arg1,\r
+                                                                 const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    return warning_message(position, id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::warning_message(const message_position& position,\r
+                                                                 const std::string& id,\r
+                                                                 const std::string& arg1,\r
+                                                                 const std::string& arg2,\r
+                                                                 const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    args.push_back(arg3);\r
+    return warning_message(position, id, args);\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // error messages\r
+\r
+  std::vector<std::string> message_handler_base::error_message(const std::string& id,\r
+                                                               const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    return error_message(message_position(), id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::error_message(const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    return error_message(id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::error_message(const std::string& id,\r
+                                                               const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    return error_message(id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::error_message(const std::string& id,\r
+                                                               const std::string& arg1,\r
+                                                               const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    return error_message(id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::error_message(const std::string& id,\r
+                                                               const std::string& arg1,\r
+                                                               const std::string& arg2,\r
+                                                               const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    args.push_back(arg3);\r
+    return error_message(id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::error_message(const message_position& position,\r
+                                                               const std::string& id,\r
+                                                               const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    return m_base_body->format_report(position, id, error_id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::error_message(const message_position& position,\r
+                                                               const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    return error_message(position, id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::error_message(const message_position& position,\r
+                                                               const std::string& id,\r
+                                                               const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    return error_message(position, id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::error_message(const message_position& position,\r
+                                                               const std::string& id,\r
+                                                               const std::string& arg1,\r
+                                                               const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    return error_message(position, id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::error_message(const message_position& position,\r
+                                                               const std::string& id,\r
+                                                               const std::string& arg1,\r
+                                                               const std::string& arg2,\r
+                                                               const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    args.push_back(arg3);\r
+    return error_message(position, id, args);\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // fatal messages\r
+\r
+  std::vector<std::string> message_handler_base::fatal_message(const std::string& id,\r
+                                                               const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    return fatal_message(message_position(), id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::fatal_message(const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    return fatal_message(id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::fatal_message(const std::string& id,\r
+                                                               const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    return fatal_message(id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::fatal_message(const std::string& id,\r
+                                                               const std::string& arg1,\r
+                                                               const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    return fatal_message(id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::fatal_message(const std::string& id,\r
+                                                               const std::string& arg1,\r
+                                                               const std::string& arg2,\r
+                                                               const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    args.push_back(arg3);\r
+    return fatal_message(id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::fatal_message(const message_position& position,\r
+                                                               const std::string& id,\r
+                                                               const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    return m_base_body->format_report(position, id, fatal_id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::fatal_message(const message_position& position,\r
+                                                               const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    return fatal_message(position, id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::fatal_message(const message_position& position,\r
+                                                               const std::string& id,\r
+                                                               const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    return fatal_message(position, id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::fatal_message(const message_position& position,\r
+                                                               const std::string& id,\r
+                                                               const std::string& arg1,\r
+                                                               const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    return fatal_message(position, id, args);\r
+  }\r
+\r
+  std::vector<std::string> message_handler_base::fatal_message(const message_position& position,\r
+                                                               const std::string& id,\r
+                                                               const std::string& arg1,\r
+                                                               const std::string& arg2,\r
+                                                               const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    args.push_back(arg3);\r
+    return fatal_message(position, id, args);\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // supplemental messages\r
+\r
+  void message_handler_base::push_supplement(const std::string& id,\r
+                                             const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    push_supplement(message_position(), id, args);\r
+  }\r
+\r
+  void message_handler_base::push_supplement(const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    push_supplement(id, args);\r
+  }\r
+\r
+  void message_handler_base::push_supplement(const std::string& id,\r
+                                             const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    push_supplement(id, args);\r
+  }\r
+\r
+  void message_handler_base::push_supplement(const std::string& id,\r
+                                             const std::string& arg1,\r
+                                             const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    push_supplement(id, args);\r
+  }\r
+\r
+  void message_handler_base::push_supplement(const std::string& id,\r
+                                             const std::string& arg1,\r
+                                             const std::string& arg2,\r
+                                             const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    args.push_back(arg3);\r
+    push_supplement(id, args);\r
+  }\r
+\r
+  void message_handler_base::push_supplement(const message_position& position,\r
+                                             const std::string& id,\r
+                                             const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    m_base_body->push_supplement(position, id, args);\r
+  }\r
+\r
+  void message_handler_base::push_supplement(const message_position& position,\r
+                                             const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    push_supplement(position, id, args);\r
+  }\r
+\r
+  void message_handler_base::push_supplement(const message_position& position,\r
+                                             const std::string& id,\r
+                                             const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    push_supplement(position, id, args);\r
+  }\r
+\r
+  void message_handler_base::push_supplement(const message_position& position,\r
+                                             const std::string& id,\r
+                                             const std::string& arg1,\r
+                                             const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    push_supplement(position, id, args);\r
+  }\r
+\r
+  void message_handler_base::push_supplement(const message_position& position,\r
+                                             const std::string& id,\r
+                                             const std::string& arg1,\r
+                                             const std::string& arg2,\r
+                                             const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    args.push_back(arg3);\r
+    push_supplement(position, id, args);\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // context\r
+\r
+  void message_handler_base::push_context (const std::string& id,\r
+                                           const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    push_context(message_position(), id, args);\r
+  }\r
+\r
+  void message_handler_base::push_context (const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    push_context(id, args);\r
+  }\r
+\r
+  void message_handler_base::push_context (const std::string& id,\r
+                                           const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    push_context(id, args);\r
+  }\r
+\r
+  void message_handler_base::push_context (const std::string& id,\r
+                                           const std::string& arg1,\r
+                                           const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    push_context(id, args);\r
+  }\r
+\r
+  void message_handler_base::push_context (const std::string& id,\r
+                                           const std::string& arg1,\r
+                                           const std::string& arg2,\r
+                                           const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    args.push_back(arg3);\r
+    push_context(id, args);\r
+  }\r
+\r
+  void message_handler_base::push_context (const message_position& position,\r
+                                           const std::string& id,\r
+                                           const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    m_base_body->push_context(position, id, args);\r
+  }\r
+\r
+  void message_handler_base::push_context (const message_position& position,\r
+                                           const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    push_context(position, id, args);\r
+  }\r
+\r
+  void message_handler_base::push_context (const message_position& position,\r
+                                           const std::string& id,\r
+                                           const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    push_context(position, id, args);\r
+  }\r
+\r
+  void message_handler_base::push_context (const message_position& position,\r
+                                           const std::string& id,\r
+                                           const std::string& arg1,\r
+                                           const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    push_context(position, id, args);\r
+  }\r
+\r
+  void message_handler_base::push_context (const message_position& position,\r
+                                           const std::string& id,\r
+                                           const std::string& arg1,\r
+                                           const std::string& arg2,\r
+                                           const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    args.push_back(arg3);\r
+    push_context(position, id, args);\r
+  }\r
+\r
+  void message_handler_base::pop_context(void) throw()\r
+  {\r
+    m_base_body->pop_context(m_base_body->context_depth()-1);\r
+  }\r
+\r
+  void message_handler_base::pop_context(unsigned depth) throw()\r
+  {\r
+    m_base_body->pop_context(depth);\r
+  }\r
+\r
+  unsigned message_handler_base::context_depth(void) const\r
+    throw()\r
+  {\r
+    return m_base_body->context_depth();\r
+  }\r
+\r
+  message_context message_handler_base::auto_push_context(const std::string& id, const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    return auto_push_context(message_position(), id, args);\r
+  }\r
+\r
+  message_context message_handler_base::auto_push_context(const std::string& id)                                                 \r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    return auto_push_context(id, args);\r
+  }\r
+\r
+  message_context message_handler_base::auto_push_context(const std::string& id,\r
+                                                          const std::string& arg1)                         \r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    return auto_push_context(id, args);\r
+  }\r
+\r
+  message_context message_handler_base::auto_push_context (const std::string& id,\r
+                                                           const std::string& arg1,\r
+                                                           const std::string& arg2) \r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    return auto_push_context(id, args);\r
+  }\r
+\r
+  message_context message_handler_base::auto_push_context(const std::string& id,\r
+                                                          const std::string& arg1,\r
+                                                          const std::string& arg2,\r
+                                                          const std::string& arg3) \r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    args.push_back(arg3);\r
+    return auto_push_context(id, args);\r
+  }\r
+\r
+  message_context message_handler_base::auto_push_context(const message_position& position,\r
+                                                          const std::string& id,\r
+                                                          const std::vector<std::string>& args)            \r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    message_context result(*this);\r
+    m_base_body->push_context(position, id, args);\r
+    return result;\r
+  }\r
+\r
+  message_context message_handler_base::auto_push_context(const message_position& position,\r
+                                                          const std::string& id)             \r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    return auto_push_context(position, id, args);\r
+  }\r
+\r
+  message_context message_handler_base::auto_push_context(const message_position& position,\r
+                                                          const std::string& id,\r
+                                                          const std::string& arg1)                         \r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    return auto_push_context(position, id, args);\r
+  }\r
+\r
+  message_context message_handler_base::auto_push_context(const message_position& position,\r
+                                                          const std::string& id,\r
+                                                          const std::string& arg1,\r
+                                                          const std::string& arg2) \r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    return auto_push_context(position, id, args);\r
+  }\r
+\r
+  message_context message_handler_base::auto_push_context(const message_position& position,\r
+                                                          const std::string& id,\r
+                                                          const std::string& arg1,\r
+                                                          const std::string& arg2,\r
+                                                          const std::string& arg3) \r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    std::vector<std::string> args;\r
+    args.push_back(arg1);\r
+    args.push_back(arg2);\r
+    args.push_back(arg3);\r
+    return auto_push_context(position, id, args);\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // iostream-based derivative uses the above base class to generate messages then uses iostream to print them\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+\r
+  class message_handler_body\r
+  {\r
+  private:\r
+    std::ostream* m_device;                        // TextIO output device\r
+    unsigned m_limit;                              // error limit\r
+    unsigned m_errors;                             // error count\r
+\r
+  public:\r
+    message_handler_body(std::ostream& device, unsigned limit) :\r
+      m_device(&device), m_limit(limit), m_errors(0)\r
+      {\r
+      }\r
+\r
+    ~message_handler_body(void)\r
+      {\r
+        device().flush();\r
+      }\r
+\r
+    std::ostream& device(void)\r
+      {\r
+        return *m_device;\r
+      }\r
+\r
+    unsigned limit(void) const\r
+      {\r
+        return m_limit;\r
+      }\r
+\r
+    void set_limit(unsigned limit)\r
+      {\r
+        m_limit = limit;\r
+      }\r
+\r
+    unsigned count(void) const\r
+      {\r
+        return m_errors;\r
+      }\r
+\r
+    void set_count(unsigned count)\r
+      {\r
+        m_errors = count;\r
+      }\r
+\r
+    void error_increment(void)\r
+      {\r
+        ++m_errors;\r
+      }\r
+\r
+    bool limit_reached(void) const\r
+      {\r
+        return m_limit > 0 && m_errors >= m_limit;\r
+      }\r
+\r
+  private:\r
+    message_handler_body(const message_handler_body&);\r
+    message_handler_body& operator=(const message_handler_body&);\r
+  };\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+\r
+  message_handler::message_handler(std::ostream& device, unsigned limit, bool show)\r
+    throw() :\r
+    message_handler_base(show), m_body(new message_handler_body(device, limit))\r
+  {\r
+  }\r
+\r
+  message_handler::message_handler(std::ostream& device,\r
+                                   const std::string& message_file, unsigned limit, bool show) \r
+    throw(message_handler_read_error) :\r
+    message_handler_base(message_file,show), m_body(new message_handler_body(device, limit))\r
+  {\r
+  }\r
+\r
+  message_handler::message_handler(std::ostream& device, const std::vector<std::string>& message_files, unsigned limit, bool show) \r
+    throw(message_handler_read_error) :\r
+    message_handler_base(message_files,show), m_body(new message_handler_body(device, limit))\r
+  {\r
+  }\r
+\r
+  message_handler::~message_handler(void)\r
+    throw()\r
+  {\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // error count\r
+\r
+  void message_handler::set_error_limit(unsigned error_limit)\r
+    throw()\r
+  {\r
+    m_body->set_limit(error_limit);\r
+  }\r
+\r
+  unsigned message_handler::error_limit(void) const\r
+    throw()\r
+  {\r
+    return m_body->limit();\r
+  }\r
+\r
+  void message_handler::reset_error_count(void)\r
+    throw()\r
+  {\r
+    m_body->set_count(0);\r
+  }\r
+\r
+  unsigned message_handler::error_count(void) const\r
+    throw()\r
+  {\r
+    return m_body->count();\r
+  }\r
+\r
+  std::ostream& message_handler::device(void)\r
+  {\r
+    return m_body->device();\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // information messages\r
+\r
+  bool message_handler::information(const std::string& id,\r
+                                    const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << information_message(id, args);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::information(const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << information_message(id);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::information(const std::string& id,\r
+                                    const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << information_message(id, arg1);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::information(const std::string& id,\r
+                                    const std::string& arg1,\r
+                                    const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << information_message(id, arg1, arg2);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::information(const std::string& id,\r
+                                    const std::string& arg1,\r
+                                    const std::string& arg2,\r
+                                    const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << information_message(id, arg1, arg2, arg3);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::information(const message_position& position,\r
+                                    const std::string& id,\r
+                                    const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << information_message(position, id, args);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::information(const message_position& position,\r
+                                    const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << information_message(position, id);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::information(const message_position& position,\r
+                                    const std::string& id,\r
+                                    const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << information_message(position, id, arg1);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::information(const message_position& position,\r
+                                    const std::string& id,\r
+                                    const std::string& arg1,\r
+                                    const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << information_message(position, id, arg1, arg2);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::information(const message_position& position,\r
+                                    const std::string& id,\r
+                                    const std::string& arg1,\r
+                                    const std::string& arg2,\r
+                                    const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << information_message(position, id, arg1, arg2, arg3);\r
+    return true;\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // warning messages\r
+\r
+  bool message_handler::warning(const std::string& id,\r
+                                const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << warning_message(id, args);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::warning(const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << warning_message(id);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::warning(const std::string& id,\r
+                                const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << warning_message(id, arg1);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::warning(const std::string& id,\r
+                                const std::string& arg1,\r
+                                const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << warning_message(id, arg1, arg2);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::warning(const std::string& id,\r
+                                const std::string& arg1,\r
+                                const std::string& arg2,\r
+                                const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << warning_message(id, arg1, arg2, arg3);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::warning(const message_position& position,\r
+                                const std::string& id,\r
+                                const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << warning_message(position, id, args);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::warning(const message_position& position,\r
+                                const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << warning_message(position, id);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::warning(const message_position& position,\r
+                                const std::string& id,\r
+                                const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << warning_message(position, id, arg1);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::warning(const message_position& position,\r
+                                const std::string& id,\r
+                                const std::string& arg1,\r
+                                const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << warning_message(position, id, arg1, arg2);\r
+    return true;\r
+  }\r
+\r
+  bool message_handler::warning(const message_position& position,\r
+                                const std::string& id,\r
+                                const std::string& arg1,\r
+                                const std::string& arg2,\r
+                                const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error)\r
+  {\r
+    device() << warning_message(position, id, arg1, arg2, arg3);\r
+    return true;\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // error messages\r
+\r
+  bool message_handler::error(const std::string& id,\r
+                              const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_limit_error)\r
+  {\r
+    device() << error_message(id, args);\r
+    m_body->error_increment();\r
+    if (m_body->limit_reached()) throw message_handler_limit_error(m_body->limit());\r
+    return false;\r
+  }\r
+\r
+  bool message_handler::error(const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_limit_error)\r
+  {\r
+    device() << error_message(id);\r
+    m_body->error_increment();\r
+    if (m_body->limit_reached()) throw message_handler_limit_error(m_body->limit());\r
+    return false;\r
+  }\r
+\r
+  bool message_handler::error(const std::string& id,\r
+                              const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_limit_error)\r
+  {\r
+    device() << error_message(id, arg1);\r
+    m_body->error_increment();\r
+    if (m_body->limit_reached()) throw message_handler_limit_error(m_body->limit());\r
+    return false;\r
+  }\r
+\r
+  bool message_handler::error(const std::string& id,\r
+                              const std::string& arg1,\r
+                              const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_limit_error)\r
+  {\r
+    device() << error_message(id, arg1, arg2);\r
+    m_body->error_increment();\r
+    if (m_body->limit_reached()) throw message_handler_limit_error(m_body->limit());\r
+    return false;\r
+  }\r
+\r
+  bool message_handler::error(const std::string& id,\r
+                              const std::string& arg1,\r
+                              const std::string& arg2,\r
+                              const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_limit_error)\r
+  {\r
+    device() << error_message(id, arg1, arg2, arg3);\r
+    m_body->error_increment();\r
+    if (m_body->limit_reached()) throw message_handler_limit_error(m_body->limit());\r
+    return false;\r
+  }\r
+\r
+  bool message_handler::error(const message_position& position,\r
+                              const std::string& id,\r
+                              const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_limit_error)\r
+  {\r
+    device() << error_message(position, id, args);\r
+    m_body->error_increment();\r
+    if (m_body->limit_reached()) throw message_handler_limit_error(m_body->limit());\r
+    return false;\r
+  }\r
+\r
+  bool message_handler::error(const message_position& position,\r
+                              const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_limit_error)\r
+  {\r
+    device() << error_message(position, id);\r
+    m_body->error_increment();\r
+    if (m_body->limit_reached()) throw message_handler_limit_error(m_body->limit());\r
+    return false;\r
+  }\r
+\r
+  bool message_handler::error(const message_position& position,\r
+                              const std::string& id,\r
+                              const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_limit_error)\r
+  {\r
+    device() << error_message(position, id, arg1);\r
+    m_body->error_increment();\r
+    if (m_body->limit_reached()) throw message_handler_limit_error(m_body->limit());\r
+    return false;\r
+  }\r
+\r
+  bool message_handler::error(const message_position& position,\r
+                              const std::string& id,\r
+                              const std::string& arg1,\r
+                              const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_limit_error)\r
+  {\r
+    device() << error_message(position, id, arg1, arg2);\r
+    m_body->error_increment();\r
+    if (m_body->limit_reached()) throw message_handler_limit_error(m_body->limit());\r
+    return false;\r
+  }\r
+\r
+  bool message_handler::error(const message_position& position,\r
+                              const std::string& id,\r
+                              const std::string& arg1,\r
+                              const std::string& arg2,\r
+                              const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_limit_error)\r
+  {\r
+    device() << error_message(position, id, arg1, arg2, arg3);\r
+    m_body->error_increment();\r
+    if (m_body->limit_reached()) throw message_handler_limit_error(m_body->limit());\r
+    return false;\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // fatal messages\r
+\r
+  bool message_handler::fatal(const std::string& id,\r
+                              const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_fatal_error)\r
+  {\r
+    device() << fatal_message(id, args);\r
+    throw message_handler_fatal_error(id);\r
+  }\r
+\r
+  bool message_handler::fatal(const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_fatal_error)\r
+  {\r
+    device() << fatal_message(id);\r
+    throw message_handler_fatal_error(id);\r
+  }\r
+\r
+  bool message_handler::fatal(const std::string& id,\r
+                              const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_fatal_error)\r
+  {\r
+    device() << fatal_message(id, arg1);\r
+    throw message_handler_fatal_error(id);\r
+  }\r
+\r
+  bool message_handler::fatal(const std::string& id,\r
+                              const std::string& arg1,\r
+                              const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_fatal_error)\r
+  {\r
+    device() << fatal_message(id, arg1, arg2);\r
+    throw message_handler_fatal_error(id);\r
+  }\r
+\r
+  bool message_handler::fatal(const std::string& id,\r
+                              const std::string& arg1,\r
+                              const std::string& arg2,\r
+                              const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_fatal_error)\r
+  {\r
+    device() << fatal_message(id, arg1, arg2, arg3);\r
+    throw message_handler_fatal_error(id);\r
+  }\r
+\r
+  bool message_handler::fatal(const message_position& position,\r
+                              const std::string& id,\r
+                              const std::vector<std::string>& args)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_fatal_error)\r
+  {\r
+    device() << fatal_message(position, id, args);\r
+    throw message_handler_fatal_error(id);\r
+  }\r
+\r
+  bool message_handler::fatal(const message_position& position,\r
+                              const std::string& id)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_fatal_error)\r
+  {\r
+    device() << fatal_message(position, id);\r
+    throw message_handler_fatal_error(id);\r
+  }\r
+\r
+  bool message_handler::fatal(const message_position& position,\r
+                              const std::string& id,\r
+                              const std::string& arg1)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_fatal_error)\r
+  {\r
+    device() << fatal_message(position, id, arg1);\r
+    throw message_handler_fatal_error(id);\r
+  }\r
+\r
+  bool message_handler::fatal(const message_position& position,\r
+                              const std::string& id,\r
+                              const std::string& arg1,\r
+                              const std::string& arg2)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_fatal_error)\r
+  {\r
+    device() << fatal_message(position, id, arg1, arg2);\r
+    throw message_handler_fatal_error(id);\r
+  }\r
+\r
+  bool message_handler::fatal(const message_position& position,\r
+                              const std::string& id,\r
+                              const std::string& arg1,\r
+                              const std::string& arg2,\r
+                              const std::string& arg3)\r
+    throw(message_handler_id_error,message_handler_format_error,message_handler_fatal_error)\r
+  {\r
+    device() << fatal_message(position, id, arg1, arg2, arg3);\r
+    throw message_handler_fatal_error(id);\r
+  }\r
+\r
+  ///////////////////////////////////////////////////////////////////////////////\r
+  // plain text\r
+\r
+  bool message_handler::plaintext(const std::string& text)\r
+  {\r
+    device() << text << std::endl;\r
+    return true;\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+\r
+} // end namespace stlplus\r
This page took 0.069817 seconds and 4 git commands to generate.