1 /*
2 OFX Support Library, a library that skins the OFX plug-in API with C++ classes.
3 Copyright (C) 2004-2005 The Open Effects Association Ltd
4 Author Bruno Nicoletti bruno@thefoundry.co.uk
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 
9 * Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright notice,
12 this list of conditions and the following disclaimer in the documentation
13 and/or other materials provided with the distribution.
14 * Neither the name The Open Effects Association Ltd, nor the names of its
15 contributors may be used to endorse or promote products derived from this
16 software without specific prior written permission.
17 
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 The Open Effects Association Ltd
30 1 Wardour St
31 London W1D 6PA
32 England
33 
34 
35 */
36 
37 /** @file This file contains the body of functions used for logging ofx problems etc...
38 
39 The log file is written to using printf style functions, rather than via c++ iostreams.
40 
41 */
42 
43 #include <cassert>
44 #include <cstdio>
45 #include <cstdarg>
46 #include <cstdlib>
47 #include <string>
48 
49 #ifdef DEBUG
50 #include <iostream>
51 #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
52 #include <direct.h>
53 #define getcwd _getcwd // stupid MSFT "deprecation" warning
54 #else
55 #include <unistd.h>
56 #endif
57 #endif
58 
59 #include "ofxsLog.h"
60 
61 namespace OFX {
62   namespace Log {
63 
64     /** @brief log file */
65     static FILE *gLogFP = 0;
66 
67     /// environment variable for the log file
68 #define kLogFileEnvVar "OFX_PLUGIN_LOGFILE"
69 
70     /** @brief the global logfile name */
71     static std::string gLogFileName(getenv(kLogFileEnvVar) ? getenv(kLogFileEnvVar) : "ofxTestLog.txt");
72 
73     /** @brief global indent level, not MP sane */
74     static int gIndent = 0;
75 
76     /** @brief Sets the name of the log file. */
setFileName(const std::string & value)77     void setFileName(const std::string &value)
78     {
79       gLogFileName = value;
80     }
81 
82     /** @brief Opens the log file, returns whether this was sucessful or not. */
open(void)83     bool open(void)
84     {
85 #ifdef DEBUG
86       if(!gLogFP) {
87         char buffer[2048];
88         char *answer = getcwd(buffer, sizeof(buffer));
89         std::cout << "INFO: OFX Log is \"" << gLogFileName << "\", working directory is \"" << answer << '\"' << std::endl;
90         gLogFP = fopen(gLogFileName.c_str(), "w");
91         if (!gLogFP) {
92           std::cout << "INFO: Failed to open OFX Log for writing" << std::endl;
93         }
94         return gLogFP != 0;
95       }
96 #endif
97       return gLogFP != 0;
98     }
99 
100     /** @brief Closes the log file. */
close(void)101     void close(void)
102     {
103       if(gLogFP) {
104         fclose(gLogFP);
105       }
106       gLogFP = 0;
107     }
108 
109     /** @brief Indent it, not MP sane at the moment */
indent(void)110     void indent(void)
111     {
112       ++gIndent;
113     }
114 
115     /** @brief Outdent it, not MP sane at the moment */
outdent(void)116     void outdent(void)
117     {
118       --gIndent;
119     }
120 
121     /** @brief do the indenting */
doIndent(void)122     static void doIndent(void)
123     {
124       if(open()) {
125         for(int i = 0; i < gIndent; i++) {
126           fputs("    ", gLogFP);
127         }
128       }
129     }
130 
131     /** @brief Prints to the log file. */
print(const char * format,...)132     void print(const char *format, ...)
133     {
134       if(open()) {
135         doIndent();
136         va_list args;
137         va_start(args, format);
138         vfprintf(gLogFP, format, args);
139         fputc('\n', gLogFP);
140         fflush(gLogFP);
141         va_end(args);
142       }
143     }
144 
145     /** @brief Prints to the log file only if the condition is true and prepends a warning notice. */
warning(bool condition,const char * format,...)146     void warning(bool condition, const char *format, ...)
147     {
148       if(condition && open()) {
149         doIndent();
150         fputs("WARNING : ", gLogFP);
151 
152         va_list args;
153         va_start(args, format);
154         vfprintf(gLogFP, format, args);
155         fputc('\n', gLogFP);
156         va_end(args);
157 
158         fflush(gLogFP);
159       }
160     }
161 
162     /** @brief Prints to the log file only if the condition is true and prepends an error notice. */
error(bool condition,const char * format,...)163     void error(bool condition, const char *format, ...)
164     {
165       if(condition && open()) {
166         doIndent();
167         fputs("ERROR : ", gLogFP);
168 
169         va_list args;
170         va_start(args, format);
171         vfprintf(gLogFP, format, args);
172         fputc('\n', gLogFP);
173         va_end(args);
174 
175         fflush(gLogFP);
176       }
177     }
178   };
179 };
180