Rozhuk Ivan ac51ab
#define _XOPEN_SOURCE 700 /* isascii() */
Rozhuk Ivan ac51ab
#undef _GNU_SOURCE /* int strerror_r() on glibc */
Toshihiro Shimizu 890ddd
#include <cerrno></cerrno>
Shinya Kitaoka 120a6e
#include <cstring> /* memset */</cstring>
Toshihiro Shimizu 890ddd
#include <vector></vector>
Shinya Kitaoka 120a6e
#include <stdexcept>  // std::domain_error(-)</stdexcept>
Toshihiro Shimizu 890ddd
#include <locale></locale>
Toshihiro Shimizu 890ddd
#include "igs_resource_msg_from_err.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
rim 26a2b2
#if defined UNICODE
Toshihiro Shimizu 890ddd
/*------ ワイド文字文字列 --> マルチバイト文字列 ------*/
rim 26a2b2
static void wcs_to_mbs(const std::wstring &wcs, std::string &mbs) {
Shinya Kitaoka 120a6e
  size_t length = 0;
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    const wchar_t *src_ptr = wcs.c_str();
Shinya Kitaoka 120a6e
    mbstate_t ss;
Shinya Kitaoka 120a6e
    ::memset(&ss, 0, sizeof(ss));
Shinya Kitaoka 120a6e
    length = ::wcsrtombs(NULL, &src_ptr, 0, &ss);
Shinya Kitaoka 120a6e
    if (length <= 0) {
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } /* 文字がないなら何もしない */
Shinya Kitaoka 120a6e
    ++length;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // std::vector<char> dst(length);</char>
Shinya Kitaoka 120a6e
  mbs.resize(length);
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    const wchar_t *src_ptr = wcs.c_str();
Shinya Kitaoka 120a6e
    mbstate_t ss;
Shinya Kitaoka 120a6e
    ::memset(&ss, 0, sizeof(ss));
Shinya Kitaoka 120a6e
    // length = ::wcsrtombs(&dst.at(0) ,&src_ptr ,length ,&ss);
Shinya Kitaoka 120a6e
    length =
Shinya Kitaoka 120a6e
        ::wcsrtombs(const_cast<char *="">(mbs.c_str()), &src_ptr, length, &ss);</char>
Shinya Kitaoka 120a6e
    if (length <= 0) {
Shinya Kitaoka 120a6e
      throw std::domain_error("wcstombs(-) got bad wide character");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // mbs = std::string(dst.begin() ,dst.end()-1);/* 終端以外を */
Shinya Kitaoka 120a6e
  mbs.erase(mbs.end() - 1); /* 終端文字を消す */
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
/*------ UNICODE宣言ならワイド文字文字列をマルチバイト文字列に変換 ------*/
rim 26a2b2
const static std::string mbs_from_ts(
Shinya Kitaoka 120a6e
    const std::basic_string<tchar> &ts) {</tchar>
Toshihiro Shimizu 890ddd
#if defined UNICODE
Shinya Kitaoka 120a6e
  std::string mbs;
rim 26a2b2
  wcs_to_mbs(ts, mbs);
Shinya Kitaoka 120a6e
  return mbs;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  /* MBCSの場合のsize()は文字数ではなくchar(byte)数,2bytes文字は2 */
Shinya Kitaoka 120a6e
  return ts;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------ エラーメッセージ表示の元関数、直接呼び出すことはしない ------*/
Shinya Kitaoka 120a6e
#include <cerrno>   // errno</cerrno>
Shinya Kitaoka 120a6e
#include <cstring>  // strerror_r()</cstring>
Shinya Kitaoka 120a6e
#include <sstream>  // std::istringstream</sstream>
Toshihiro Shimizu 890ddd
#include "igs_resource_msg_from_err.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const std::string igs::resource::msg_from_err_(
Shinya Kitaoka 120a6e
    const std::basic_string<tchar> &tit, const int erno,</tchar>
Shinya Kitaoka 120a6e
    const std::string &file, const std::string &line,
Shinya Kitaoka 120a6e
    const std::string &pretty_function, const std::string &comp_type,
Shinya Kitaoka 120a6e
    const std::string &gnuc, const std::string &gnuc_minor,
Shinya Kitaoka 120a6e
    const std::string &gnuc_patchlevel, const std::string &gnuc_rh_release,
Shinya Kitaoka 120a6e
    const std::string &date, const std::string &time) {
Shinya Kitaoka 120a6e
  std::string errmsg;
Shinya Kitaoka 120a6e
  errmsg += '\"';
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* フルパスで入ってきた場合ファイル名だけにする */
Shinya Kitaoka 120a6e
  std::string::size_type index = file.find_last_of("/\\");
Shinya Kitaoka 120a6e
  if (std::basic_string<tchar>::npos != index) {</tchar>
Shinya Kitaoka 120a6e
    errmsg += file.substr(index + 1);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    errmsg += file;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  errmsg += ':';
Shinya Kitaoka 120a6e
  errmsg += line;
Shinya Kitaoka 120a6e
  errmsg += ':';
Shinya Kitaoka 120a6e
  errmsg += comp_type;
Shinya Kitaoka 120a6e
  errmsg += ':';
Shinya Kitaoka 120a6e
  errmsg += gnuc;
Shinya Kitaoka 120a6e
  errmsg += '.';
Shinya Kitaoka 120a6e
  errmsg += gnuc_minor;
Shinya Kitaoka 120a6e
  errmsg += '.';
Shinya Kitaoka 120a6e
  errmsg += gnuc_patchlevel;
Shinya Kitaoka 120a6e
  errmsg += '-';
Shinya Kitaoka 120a6e
  errmsg += gnuc_rh_release;
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    std::istringstream ist(date);
Shinya Kitaoka 120a6e
    std::string month, day, year;
Shinya Kitaoka 120a6e
    ist >> month;
Shinya Kitaoka 120a6e
    ist >> day;
Shinya Kitaoka 120a6e
    ist >> year;
Shinya Kitaoka 120a6e
    errmsg += ':';
Shinya Kitaoka 120a6e
    errmsg += year;
Shinya Kitaoka 120a6e
    errmsg += ':';
Shinya Kitaoka 120a6e
    errmsg += month;
Shinya Kitaoka 120a6e
    errmsg += ':';
Shinya Kitaoka 120a6e
    errmsg += day;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  errmsg += ':';
Shinya Kitaoka 120a6e
  errmsg += time;
Shinya Kitaoka 120a6e
  errmsg += '\"';
Shinya Kitaoka 120a6e
  errmsg += ' ';
Shinya Kitaoka 120a6e
  errmsg += '\"';
Shinya Kitaoka 120a6e
  errmsg += pretty_function;
Shinya Kitaoka 120a6e
  errmsg += '\"';
Shinya Kitaoka 120a6e
  errmsg += ' ';
Shinya Kitaoka 120a6e
  errmsg += '\"';
Shinya Kitaoka 120a6e
  if (0 < tit.size()) {
rim 26a2b2
    errmsg += mbs_from_ts(tit);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (0 != erno) {
Shinya Kitaoka 120a6e
    errmsg += ':';
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if defined __HP_aCC
Shinya Kitaoka 120a6e
    /*
Shinya Kitaoka 120a6e
HP-UX(v11.23)では、strerror_r()をサポートしない。
Shinya Kitaoka 120a6e
注意::strerror()はThread SafeではなくMulti Threadでは正常動作しない
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
    errmsg += ::strerror(erno);
Érico Rolim 462744
#elif !defined(__APPLE__)
Shinya Kitaoka 120a6e
    /*
Shinya Kitaoka 120a6e
http://japanese-linux-man-pages.coding-school.com/man/X_strerror_r-3
Shinya Kitaoka 120a6e
より、POSIX.1.2002で規定されたXSI準拠のバージョンのstrerror_r()
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
    char buff[4096];
Shinya Kitaoka 120a6e
    const int ret = ::strerror_r(erno, buff, sizeof(buff));
Shinya Kitaoka 120a6e
    if (0 == ret) {
Shinya Kitaoka 120a6e
      errmsg += buff;
Shinya Kitaoka 120a6e
    } else if (-1 == ret) {
rim 26a2b2
      switch(errno) {
Shinya Kitaoka 120a6e
      case EINVAL:
Shinya Kitaoka 120a6e
        errmsg +=
Shinya Kitaoka 120a6e
            "strerror_r() gets Error : The value of errnum is not a "
Shinya Kitaoka 120a6e
            "valid error number.";
Shinya Kitaoka 120a6e
        /* errnum の値が有効なエラー番号ではない */
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      case ERANGE:
Shinya Kitaoka 120a6e
        errmsg +=
Shinya Kitaoka 120a6e
            "strerror_r() gets Error : Insufficient storage was "
Shinya Kitaoka 120a6e
            "supplied via strerrbuf and buflen  to contain the "
Shinya Kitaoka 120a6e
            "generated message string.";
Shinya Kitaoka 120a6e
        /* エラーコードを説明する文字列のために、
Shinya Kitaoka 120a6e
充分な領域が確保できな かった */
Shinya Kitaoka 120a6e
        break;
rim 26a2b2
      default:
Shinya Kitaoka 120a6e
        errmsg += "strerror_r() gets Error and Returns bad errno";
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      errmsg += "strerror_r() returns bad value";
Shinya Kitaoka 120a6e
    }
Érico Rolim 462744
#else
Shinya Kitaoka 120a6e
    char buff[4096];
Shinya Kitaoka 120a6e
    int ret = ::strerror_r(erno, buff, sizeof(buff));
Shinya Kitaoka 120a6e
    if (!ret) {
Shinya Kitaoka 120a6e
      errmsg += buff;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  errmsg += '\"';
Shinya Kitaoka 120a6e
  return errmsg;
Toshihiro Shimizu 890ddd
}