IOutputStream.cc 3.25 KB
Newer Older
1 2 3 4 5 6 7
// (C) Copyright 2016 by Autodesk, Inc.

#include "Base/Security/Mandatory.hh"
#include "IOutputStream.hh"
#include "Base/Code/CodeLink.hh"
#include "Base/Utils/ThrowError.hh"

Martin Heistermann's avatar
Martin Heistermann committed
8 9 10 11 12 13
#include <cstring>

#if COMISO_BOOST_AVAILABLE
#  include <boost/filesystem.hpp>
#endif

14 15 16 17
#include <string>

namespace Base {

18
IOutputStream& operator<<(IOutputStream& _os, const int _i)
19
{
20
  return _os.print(_i);
21 22
}

23
IOutputStream& operator<<(IOutputStream& _os, const double _d)
24
{
25
  return _os.print(_d);
26 27
}

28
IOutputStream& operator<<(IOutputStream& _os, const char* const _s)
29
{
30
  return _os.print(_s);
31 32
}

33
IOutputStream& operator<<(IOutputStream& _os, const char _c)
34
{
35
  return _os.print(_c);
36 37
}

38
IOutputStream& operator<<(IOutputStream& _os, const size_t _i)
39
{
40
  return _os.print(_i);
41 42
}

43
#ifdef UINT_SIZET_DIFFER
44
IOutputStream& operator<<(IOutputStream& _os, const unsigned int _i)
45
{
46
  return _os.print(size_t(_i));
47
}
48
#endif//UINT_SIZET_DIFFER
49

50
IOutputStream& operator<<(IOutputStream& _os, const float _f)
51
{
52
  return _os.print((double)_f);
53 54
}

55
IOutputStream& operator<<(IOutputStream& _os, const std::string& _s)
56
{
57
  return _os.print(_s.c_str());
58 59
}

60
IOutputStream& operator<<(IOutputStream& _os, const Command& _co)
61
{
62
  return _os.print(_co);
63 64
}

65 66 67 68 69 70
IOutputStream& operator<<(IOutputStream& _os, const Command::Type _cmd_type)
{
  return _os.print(Command(_cmd_type));
}


Martin Heistermann's avatar
Martin Heistermann committed
71
#if COMISO_BOOST_AVAILABLE
72
IOutputStream& operator<<(IOutputStream& _os, const boost::filesystem::path& _path)
73
{
74 75
  return _os << '\"' << _path.string().c_str() << '\"';
}
Martin Heistermann's avatar
Martin Heistermann committed
76
#endif // COMISO_BOOST_AVAILABLE
77

78 79 80 81 82 83 84 85
// Represent this as an object in the stream, to preserve the streaming order
struct FunctionNameFilter
{
  FunctionNameFilter(const char* _fnct) : fnct_(_fnct) {}
  const char* fnct_;
};

IOutputStream& operator<<(IOutputStream& _os, const FunctionNameFilter& _fnf)
86 87 88 89 90 91
{
  // The goal is to filter unstable text from the function name, e.g., lambdas.
  // MSVC Lambda function name: <lambda_136f4d101172d40b57aea5f0078ce711>
  // Multiple lambdas could be in the same function?
  // TODO: this naming pattern is compiler/platform dependent
  // gcc lambda name is <lambdaX>
92
  
93
  const char lmbd[] = "<lambda";
94
  const char* fnct = _fnf.fnct_;
95 96 97
  for(;;)
  {
    const char* lmbd_pos = strstr(fnct, lmbd);
98
    if (lmbd_pos == NULL)
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
    {// print the rest of the function name
      _os << fnct;
      break;
    }
    // print everything until here (char by char, not optimal, but easy)
    for (; fnct != lmbd_pos; ++fnct)
      _os << *fnct;
    _os << lmbd; // now print lambda
    // and skip until > or end of string
    for (; *fnct != '>' && *fnct != '\0'; ++fnct)
      ;
  } 
  return _os;
}

114 115 116 117 118 119 120 121
IOutputStream& operator<<(IOutputStream& _os, const CodeLink& _lnk)
{
#ifdef WIN32
  const char path_sep = '\\';
#else//!WIN32
  const char path_sep = '/';
#endif//WIN32
  
122 123
  const char* flnm_pntr = strrchr(_lnk.file, path_sep);
  if (flnm_pntr == NULL)
124 125 126 127
    flnm_pntr = _lnk.file;
  else
    ++flnm_pntr;

128
  return _os << "@ [" << FunctionNameFilter(_lnk.fnct) << "() in " 
129 130 131 132 133 134 135 136
    << flnm_pntr << ":" << _lnk.line << "]";
}

}//namespace Base

#ifdef DEB_ON
namespace Debug {

137
Base::IOutputStream& operator<<(Base::IOutputStream& _os, 
138 139
  const ThrowInfo& _thrw_info)
{
140
  return _os << "thrown in " << _thrw_info.modl << " " << _thrw_info.lnk;
141 142 143 144
}

}//namespace Debug
#endif//DEB_ON