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
00030
00031
00032
00033
00034 #include "CFrontError.hpp"
00035 #include <cstdlib>
00036 #include <cstring>
00037 #include "config.h"
00038
00039 #if ! HAVE_DECL_STRNDUP
00040 char *
00041 strndup(const char *s, size_t n)
00042 {
00043 unsigned int len = strlen(s);
00044 char *p;
00045 if (len > n) {
00046 len = n;
00047 }
00048 p = (char*)malloc(len+1);
00049 memcpy(p, s, len);
00050 p[len] = '\0';
00051 return p;
00052 }
00053 #endif
00054
00055 #define MAX_TOKEN_LEN 256
00056 #define MAX_MESSAGE_LEN 1024
00057
00058 using namespace cfront;
00059
00060 void ctrump_log(struct ctrump_loginfo* logInfo, int logLevel,
00061 enum ctrump_error_code ecode,
00062 const char* message, const char* formatStr,
00063 unsigned int numTokens, const char** tokens,
00064 const char* filename, int line, int column)
00065 {
00066 logInfo->logLevel = logLevel;
00067 logInfo->code = ecode;
00068 logInfo->message = message;
00069 logInfo->formatStr = formatStr;
00070 logInfo->numTokens = numTokens;
00071 logInfo->tokens = tokens;
00072 logInfo->filename = filename;
00073 logInfo->line = line;
00074 logInfo->column = column;
00075
00076 #if SHOW_ERR_IMMEDIATELY || SHOW_WARNING
00077 ctrump_report_log(logInfo);
00078 #endif
00079 }
00080
00081 void ctrump_free_log(struct ctrump_loginfo* logInfo)
00082 {
00083 if (logInfo->numTokens != 0) {
00084 for (unsigned int i = 0; i < logInfo->numTokens; ++i) {
00085 std::free(const_cast<char*>(logInfo->tokens[i]));
00086 }
00087 std::free(logInfo->tokens);
00088 logInfo->tokens = NULL;
00089 }
00090 if (logInfo->message != NULL) {
00091 std::free(const_cast<char*>(logInfo->message));
00092 logInfo->message = NULL;
00093 }
00094 }
00095
00096 void ctrump_report_log(struct ctrump_loginfo* logInfo)
00097 {
00098 if (logInfo->logLevel == CTRUMP_LOGLEVEL_ERROR) {
00099 fprintf(stderr, "error:");
00100 } else if (logInfo->logLevel == CTRUMP_LOGLEVEL_WARNING) {
00101 fprintf(stderr, "warning:");
00102 }
00103 fprintf(stderr, "[%s:%d:%d]: ",
00104 logInfo->filename, logInfo->line, logInfo->column);
00105 char* msg = ctrump_get_loginfo_message(logInfo);
00106 fprintf(stderr, "%s\n", msg);
00107 std::free(msg);
00108 }
00109
00110 void ctrump_add_log(Logs* logs, int logLevel, enum ctrump_error_code code,
00111 const char* fmt, const cfront::Location& location, ...)
00112 {
00113 ctrump_loginfo linfo;
00114 va_list ap;
00115 typedef std::vector<const char*> TokenStrs;
00116 TokenStrs tokenStrs;
00117
00118 va_start(ap, location);
00119 va_list sap;
00120 va_copy(sap, ap);
00121
00122 char* message = static_cast<char*>(std::malloc(MAX_MESSAGE_LEN));
00123 std::memset(message, 0, MAX_MESSAGE_LEN);
00124 vsnprintf(message, MAX_MESSAGE_LEN, fmt, sap);
00125
00126 unsigned int numTokens = 0;
00127 const char* token;
00128 while ((token = va_arg(ap, const char*)) != NULL) {
00129 char* logToken = strndup(token, MAX_TOKEN_LEN);
00130 tokenStrs.push_back(logToken);
00131 numTokens++;
00132 }
00133
00134 const char** logTokens = static_cast<const char**>
00135 (std::malloc(numTokens * sizeof(const char**)));
00136 std::copy(tokenStrs.begin(), tokenStrs.end(), logTokens);
00137 const std::string& filepathStr = location.filePath;
00138 char* filepath = (char*) std::malloc(filepathStr.size() + 1);
00139 std::strncpy(filepath, filepathStr.c_str(), filepathStr.size() + 1);
00140 ctrump_log(&linfo, logLevel, code, message, fmt,
00141 numTokens, logTokens, filepath, location.line, location.column);
00142 if (logLevel == CTRUMP_LOGLEVEL_ERROR) {
00143 logs->push_back(linfo);
00144 }
00145 }
00146
00147 char* ctrump_get_loginfo_message(struct ctrump_loginfo *error)
00148 {
00149 return strndup(error->message, MAX_MESSAGE_LEN);
00150 }