00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <mex.h>
00030 #include <rosmatlab/log.h>
00031 #include <rosmatlab/exception.h>
00032 #include <rosmatlab/options.h>
00033
00034 #include <ros/console.h>
00035 #include <boost/algorithm/string.hpp>
00036 #include <cstdarg>
00037 #include <boost/shared_array.hpp>
00038
00039 namespace rosmatlab {
00040 namespace log {
00041
00042 #define INITIAL_BUFFER_SIZE 4096
00043 static boost::shared_array<char> g_print_buffer(new char[INITIAL_BUFFER_SIZE]);
00044 static size_t g_print_buffer_size = INITIAL_BUFFER_SIZE;
00045
00046 static bool getLevel(const std::string& str, Level &level) {
00047 if (boost::iequals(str, "debug")) { level = Debug; return true; }
00048 if (boost::iequals(str, "info")) { level = Info; return true; }
00049 if (boost::iequals(str, "warn")) { level = Warn; return true; }
00050 if (boost::iequals(str, "error")) { level = Error; return true; }
00051 if (boost::iequals(str, "fatal")) { level = Fatal; return true; }
00052 return false;
00053 }
00054
00055 static bool getLevel(double dbl, Level &level) {
00056 if (isnan(dbl)) return false;
00057 unsigned int i = static_cast<unsigned int>(dbl);
00058 if (i >= Count) return false;
00059 level = static_cast<Level>(i);
00060 return true;
00061 }
00062
00063 void log(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00064 {
00065 Level level = ::ros::console::levels::Info;
00066 std::string name;
00067 std::string message;
00068
00069
00070 if (nrhs == 0) {
00071 return;
00072 } else if (nrhs == 1) {
00073 message = Options::getString(prhs[0]);
00074 } else if (nrhs == 2) {
00075 std::string arg1 = Options::getString(prhs[0]);
00076 if (!getLevel(arg1, level) && !getLevel(Options::getDoubleScalar(prhs[0]), level)) name = arg1;
00077 message = Options::getString(prhs[1]);
00078 } else if (nrhs > 2) {
00079 if (!getLevel(Options::getString(prhs[0]), level) && !getLevel(Options::getDoubleScalar(prhs[0]), level)) {
00080 throw Exception("Could not evaluate first argument as log level (Debug, Info, Warn, Error, Fatal)");
00081 }
00082 name = Options::getString(prhs[1]);
00083 message = Options::getString(prhs[2]);
00084 }
00085
00086 log(level, name.c_str(), message.c_str());
00087 }
00088
00089 void log(Level level, int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00090 {
00091 std::string name;
00092 std::string message;
00093
00094
00095 if (nrhs == 0) {
00096 return;
00097 } else if (nrhs == 1) {
00098 message = Options::getString(prhs[0]);
00099 } else if (nrhs == 2) {
00100 name = Options::getString(prhs[0]);
00101 message = Options::getString(prhs[1]);
00102 }
00103
00104 log(level, name.c_str(), message.c_str());
00105 }
00106
00107 void log(Level level, const char *name, const char *fmt, ...)
00108 {
00109 std::string file;
00110 std::string function;
00111 int line = 0;
00112
00113 va_list args;
00114 va_start(args, fmt);
00115 ros::console::vformatToBuffer(g_print_buffer, g_print_buffer_size, fmt, args);
00116 va_end(args);
00117 std::stringstream message(std::string(g_print_buffer.get()));
00118
00119
00120 mxArray *stack;
00121 mexCallMATLAB(1, &stack, 0, 0, "dbstack");
00122 if (mxIsStruct(stack) && mxGetNumberOfElements(stack) > 0) {
00123 file = Options::getString(mxGetField(stack, 0, "file"));
00124 function = Options::getString(mxGetField(stack, 0, "name"));
00125 line = static_cast<int>(Options::getDoubleScalar(mxGetField(stack, 0, "line")));
00126 }
00127
00128
00129 std::string logger_name;
00130 if (name && strlen(name) > 0) {
00131 logger_name = std::string(ROSCONSOLE_DEFAULT_NAME) + "." + name;
00132 } else {
00133 logger_name = std::string(ROSCONSOLE_DEFAULT_NAME);
00134 }
00135
00136
00137 do {
00138 ROSCONSOLE_DEFINE_LOCATION(true, level, logger_name);
00139 if (ROS_UNLIKELY(enabled))
00140 {
00141 ::ros::console::print(0, loc.logger_, loc.level_, message, file.c_str(), line, function.c_str());
00142 }
00143
00144 if (enabled) {
00145 static const std::string level_strings[] = { "Debug", "Info", "Warn", "Error", "Fatal" };
00146 std::stringstream output;
00147 output << "[" << level_strings[level] << "] [" << ros::WallTime::now() << "] " << message.str();
00148 mexPrintf(output.str().c_str());
00149 mexPrintf("\n");
00150 }
00151 } while(0);
00152 }
00153
00154 }
00155 }