aboutsummaryrefslogtreecommitdiff
path: root/externals/g3dlite/G3D.lib/source/Log.cpp
blob: 13cea7a31f0eb7819e8dc40e87ad61e93efbfe66 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/**
  @file Log.cpp

  @maintainer Morgan McGuire, morgan@graphics3d.com
  @created 2001-08-04
  @edited  2005-07-01
 */

#include "G3D/platform.h"
#include "G3D/Log.h"
#include "G3D/format.h"
#include "G3D/Array.h"
#include "G3D/fileutils.h"
#include <time.h>

#ifdef G3D_WIN32
    #include <imagehlp.h>
#else
    #include <stdarg.h>
#endif

namespace G3D {

void logPrintf(const char* fmt, ...) {
	va_list arg_list;
	va_start(arg_list, fmt);
    Log::common()->vprintf(fmt, arg_list);
    va_end(arg_list);
}


Log* Log::commonLog = NULL;

Log::Log(const std::string& filename, int stripFromStackBottom) : 
    stripFromStackBottom(stripFromStackBottom) {

    this->filename = filename;

    logFile = fopen(filename.c_str(), "w");

    if (logFile == NULL) {
        std::string drive, base, ext;
        Array<std::string> path;
        parseFilename(filename, drive, path, base, ext);
        std::string logName = base + ((ext != "") ? ("." + ext) : ""); 

        // Write time is greater than 1ms.  This may be a network drive.... try another file.
        #ifdef G3D_WIN32
           logName = std::string(std::getenv("TEMP")) + logName;
        #else
            logName = std::string("/tmp/") + logName;
        #endif

        logFile = fopen(logName.c_str(), "w");
    }

    // Turn off buffering.
    setvbuf(logFile, NULL, _IONBF, 0);

    fprintf(logFile, "Application Log\n");
    time_t t;
    time(&t);
    fprintf(logFile, "Start: %s\n", ctime(&t));
    fflush(logFile);

    if (commonLog == NULL) {
        commonLog = this;
    }
}


Log::~Log() {
    section("Shutdown");
    println("Closing log file");
    
    // Make sure we don't leave a dangling pointer
    if (Log::commonLog == this) {
        Log::commonLog = NULL;
    }

    fclose(logFile);
}


FILE* Log::getFile() const {
    return logFile;
}

Log* Log::common() {
    if (commonLog == NULL) {
        commonLog = new Log();
    }
    return commonLog;
}


std::string Log::getCommonLogFilename() {
    return common()->filename;
}


void Log::section(const std::string& s) {
    fprintf(logFile, "_____________________________________________________\n");
    fprintf(logFile, "\n    ###    %s    ###\n\n", s.c_str());
}


void __cdecl Log::printf(const char* fmt, ...) {
    printHeader();

	va_list arg_list;
	va_start(arg_list, fmt);
    print(vformat(fmt, arg_list));
    va_end(arg_list);
}


void __cdecl Log::vprintf(const char* fmt, va_list argPtr) {
    vfprintf(logFile, fmt, argPtr);
}


void Log::print(const std::string& s) {
    printHeader();
    fprintf(logFile, "%s", s.c_str());
}


void Log::println(const std::string& s) {
    printHeader();
    fprintf(logFile, "%s\n", s.c_str());
}


void Log::printHeader() {
    time_t t;
    if (time(&t) != ((time_t)-1)) {
        /*
        char buf[32];
        strftime(buf, 32, "[%H:%M:%S]", localtime(&t));
    
         Removed because this doesn't work on SDL threads.

        #ifdef _DEBUG
            std::string bt = getBacktrace(15, 2, stripFromStackBottom);
            fprintf(logFile, "\n %s %s\n\n", buf, bt.c_str());
        #endif

        fprintf(logFile, "\n %s \n", buf);
        */

    } else {
        println("[Error getting time]");
    }
}

}