TEMU  4.4
The Terma Emulator
Logging.h
Go to the documentation of this file.
1 //===-- temu-c/Logging.h - Logging functions --------------------*- C++ -*-===//
2 //
3 // TEMU: The Terma Emulator
4 // (c) Terma 2015
5 // Authors: Mattias Holm <maho (at) terma.com>
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef TEMU_LOGGING_H
10 #define TEMU_LOGGING_H
11 
12 #include "temu-c/Support/Attributes.h"
13 #include "temu-c/Support/Objsys.h"
14 #include <stdarg.h>
15 #include <stdio.h>
16 
17 /*!
18  * \file Logging.h
19  *
20  * TEMU logging functions. TEMU provides a logging facility to log
21  * messages from models. These messages can be of a number of severity
22  * levels and will be assigned to a model object. When printing the
23  * message will be formatted as follows: "<severity> : <object> :
24  * message\n", where <severity> is one of debug, info, warning, error
25  * and critical and <object> is the name of the object generating the
26  * log message.
27  *
28  * TEMU provides a "critical" log message, these messages are
29  * critical in the sense that after they have been logged, the
30  * emulator will terminate abnormally. Critical messages should never
31  * happen normally are typically placed in unreachable code locations.
32  *
33  * Error messages imply that something failed but that the caller of
34  * the failed function is expected to take action in some way. Typical
35  * case is when opening a file (e.g. an SREC or ELF binary) specified
36  * by the user and the file did not exist.
37  *
38  * Warning message exist to notify the user about something that may
39  * be an issue, but not necessarily is. An example is in the object
40  * system temu_checkSanity function, which will check whether objects
41  * are properly configured by being fully connected.
42  *
43  * Info messages are normal messages, that exist solely to provide
44  * information to the user. For example, a model may print status info
45  * after it has been created.
46  *
47  * Debug messages should not occur during normal use, and the debug
48  * function will be a static inline function with no body when
49  * building a model with -DNDEBUG. This is important, because the
50  * compiler will eliminate the call to the empty function, while still
51  * remaining fully typesafe and NOT being a macro.
52  *
53  */
54 
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58 
59 /*!
60  * Logging levels corresponds roughly to some of the RFC 5424 severity
61  * levels.
62  */
63 typedef enum temu_LogLevel {
64  teLL_Fatal = 0, //!< Fatal, emulator cannot keep on running
65  teLL_Error, //!< Error happened, in principle critical but up to user
66  teLL_Warning, //!< Warnings
67  teLL_Info, //!< Normal messages
68  teLL_Trace, //!< Trace messages, not compiled away
69  teLL_Debug, //!< Debug
70 } temu_LogLevel;
71 
72 /*!
73  * Set logging level. Messages will be logged if they are of the set
74  * level or higher priority.
75  *
76  * \param LogLevel The logging level.
77  */
79 
80 /*!
81  * Set logging function.
82  *
83  * It is possible to provide a custom function for handling logging
84  * messages from TEMU. This can be used by a simulator that provides
85  * a centralized logging facility to also handle TEMU logging
86  * messages. By default, the messages will be printed to stderr using
87  * fputs. Note that messages will be terminated by "\n\0", so if your
88  * logging system adds a linefeed, the message may need to be
89  * transformed.
90  *
91  * \param LogFunc Logging function to use. NULL to restore the default.
92  */
93 TEMU_API void temu_logSetFunc(void (*LogFunc)(const char *));
94 
95 /*!
96  * Set advanced logging function.
97  *
98  * It is possible to provide a custom function for handling logging
99  * messages from TEMU. This can be used by a simulator that provides
100  * a centralized logging facility to also handle TEMU logging
101  * messages. By default, the messages will be printed to stderr using
102  * fputs.
103  *
104  * The advanced logging function does not get messages with a terminating linefeed.
105  * In addition, the function receives the object, category and log level as its own parameters.
106  *
107  * The message does not contain object name / time stamps.
108  * The integrator would be expected to extract the time stamp from the objects time source if set.
109  *
110  * LogFunc will take the following parameters:
111  *
112  * User data:: Void pointer passed to UserData parameter (may be NULL).
113  * Object pointer:: Pointer to object issuing the log message (may be NULL).
114  * Category:: Category id of log message.
115  * Log level:: Severity of logging message.
116  * Message:: The log message, as a '\0' terminated string.
117  *
118  * \param LogFunc Logging function to use. NULL to restore the default.
119  * \param UserData User data to pass to the logging functions first parameter.
120  */
121 TEMU_API void
122 temu_logSetAdvancedFunc(void (*LogFunc)(void *, temu_Object *, unsigned, temu_LogLevel, const char *), void *UserData);
123 
124 
125 /*!
126  * Set the logging file for the default logging function. Pass NULL to
127  * restore default (stderr).
128  *
129  * \param FP Logging file pointer, NULL to restore default.
130  */
132 
133 /*!
134  * Enable colours on logging
135  * \param Enable 0 to disable colours, 1 to enable
136  */
138 
139 /*!
140  * Log a message with fatal severity; The program will
141  * terminate after calling this \param Obj is the source of the log message
142  * \param Msg The message to log
143  */
144 TEMU_API void temu_logFatal(const void *Obj, const char *Msg, ...)
145  __attribute__((noreturn)) __attribute__((format(printf, 2, 3)));
146 
147 /*!
148  * Log a message with error severity
149  * \param Obj is the source of the log message
150  * \param Msg The message to log
151  */
152 TEMU_API void temu_logError(const void *Obj, const char *Msg, ...)
153  __attribute__((format(printf, 2, 3)));
154 
155 /*!
156  * Log a message with warning severity
157  * \param Obj is the source of the log message
158  * \param Msg The message to log
159  */
160 TEMU_API void temu_logWarning(const void *Obj, const char *Msg, ...)
161  __attribute__((format(printf, 2, 3)));
162 
163 /*!
164  * Log a message with info severity
165  * \param Obj is the source of the log message
166  * \param Msg The message to log
167  */
168 TEMU_API void temu_logInfo(const void *Obj, const char *Msg, ...)
169  __attribute__((format(printf, 2, 3)));
170 
171 /*!
172  * Log a message with trace severity
173  * \param Obj is the source of the log message
174  * \param Msg The message to log
175  */
176 TEMU_API void temu_logTrace(const void *Obj, const char *Msg, ...)
177  __attribute__((format(printf, 2, 3)));
178 
179 /*!
180  * Log a message with debug severity
181  *
182  * \warning This function is intended for internal use only. Do not
183  * call this directly. Use temu_logDebug() instead.
184  *
185  * \param Obj is the source of the log message
186  * \param Msg The message to log
187  */
188 TEMU_API void temu_logDebugFunc(const void *Obj, const char *Msg, ...)
189  __attribute__((format(printf, 2, 3)));
190 
191 #ifdef NDEBUG
192 static inline void
193 temu_logDebug(const void *Obj TEMU_UNUSED, const char *Msg TEMU_UNUSED, ...)
194 {
195  ; // Nothing
196 }
197 
198 #else
199 
200 #define temu_logDebug temu_logDebugFunc
201 
202 #endif
203 
204 /*
205  * New logging API
206  *
207  * The new logging API provides specialised logging for temu_Object
208  * derived classes. They cannot be used by external classes.
209  *
210  * EXPERIMENTAL API New logging API. The New logging API provides
211  * improved logging support. Among the features include custom
212  * logging categories and per device per categor control of the
213  * logging. 16 logging categories are supported, of which the first
214  * 8 are reserved for TEMU (i.e. global categories).
215  * The next 8 can be controlled per class.
216  *
217  * The reserved categories is split in three main categories (sim,
218  * target and config). These are further subdivided in severity.
219  *
220  * The config category is used to inform users during the
221  * configuration phase or any issues detected with dynamic
222  * configuration. For example, a device with an IRQ property may be
223  * restricted to e.g. 8 different IRQs, if the user sets another value
224  * than the allowed ones then a config error would be logged.
225  *
226  * The target category is for errors triggered by target software, for
227  * example writing a register would be logged with
228  * temu_logTargetDebug(). Note that the category is intended for
229  * direct effects, which is mostly related to MMIO activity.
230  *
231  * The sim category is for other errors caused by e.g. invalid use of
232  * the TEMU APIs, or other failures.
233  *
234  * A nice feature of this API is the support for user definable
235  * categories. These categories are per class. But category enabling
236  * is controlled per object and globally. A category can be added to a
237  * class using temu_addLoggingCategory() (see Objsys.h), and queried
238  * by id using temu_getLoggingCategory(). The ID can then be used in
239  * calls to temu_logToCategory().
240  *
241  */
242 
243 // User reserved categories are those above 8
244 #define teLC_FirstUserCat 8
245 
246 #define teLC_DefaultCat 0
247 #define teLC_SimCat 1
248 #define teLC_TargetCat 2
249 #define teLC_ConfigCat 3
250 
251 TEMU_API void temu_logToCategoryVA(const void *Obj, unsigned Category,
252  temu_LogLevel Severity, const char *Msg,
253  va_list Args);
254 
255 /*!
256  * Set severity for specific category.
257  * \param Obj Object for which to modify logging severity
258  * \param Category Category to change severity for (e.g. teLC_DefaultCat)
259  * \param Severity The log level for which messages shall be emitted.
260  */
261 TEMU_API void temu_logSetSeverity(void *Obj, unsigned Category,
263 
264 /*!
265  * Log message in the numbered category
266  * \param Obj Object that is the source of the log message
267  * \param Category Category of message (e.g. `teLC_DefaultCat`)
268  * \param Severity The log level for which the message shall be emitted.
269  * \param Msg Printf formatted message string.
270  */
271 TEMU_API void temu_logToCategory(const void *Obj, unsigned Category,
272  temu_LogLevel Severity, const char *Msg, ...)
273  __attribute__((format(printf, 4, 5)));
274 
275 /*!
276  * Log fatal issue Fatal messages result in termination of the program
277  * after the message.
278  *
279  * \param Obj Object
280  * \param Msg Printf formatted message string
281  */
282 TEMU_API void temu_logSimFatal(const void *Obj, const char *Msg, ...)
283  __attribute__((noreturn)) __attribute__((format(printf, 2, 3)));
284 
285 /*!
286  * Log simulation error
287  *
288  * \param Obj Object
289  * \param Msg Printf formatted message string
290  */
291 TEMU_API void temu_logSimError(const void *Obj, const char *Msg, ...)
292  __attribute__((format(printf, 2, 3)));
293 
294 /*!
295  * Log simulation warning
296  *
297  * \param Obj Object
298  * \param Msg Printf formatted message string
299  */
300 TEMU_API void temu_logSimWarning(const void *Obj, const char *Msg, ...)
301  __attribute__((format(printf, 2, 3)));
302 
303 /*!
304  * Log simulation info
305  *
306  * \param Obj Object
307  * \param Msg Printf formatted message string
308  */
309 TEMU_API void temu_logSimInfo(const void *Obj, const char *Msg, ...)
310  __attribute__((format(printf, 2, 3)));
311 
312 /*!
313  * Log target fatal error
314  * This should typically never happen, but it may be convenient
315  * in some cases.
316  *
317  * \param Obj Object
318  * \param Msg Printf formatted message string
319  */
320 TEMU_API void temu_logTargetFatal(const void *Obj, const char *Msg, ...)
321  __attribute__((noreturn)) __attribute__((format(printf, 2, 3)));
322 
323 /*!
324  * Log target error
325  *
326  * \param Obj Object
327  * \param Msg Printf formatted message string
328  */
329 TEMU_API void temu_logTargetError(const void *Obj, const char *Msg, ...)
330  __attribute__((format(printf, 2, 3)));
331 
332 /*!
333  * Log target warning
334  *
335  * \param Obj Object
336  * \param Msg Printf formatted message string
337  */
338 TEMU_API void temu_logTargetWarning(const void *Obj, const char *Msg, ...)
339  __attribute__((format(printf, 2, 3)));
340 
341 /*!
342  * Log target info
343  *
344  * \param Obj Object
345  * \param Msg Printf formatted message string
346  */
347 
348 TEMU_API void temu_logTargetInfo(const void *Obj, const char *Msg, ...)
349  __attribute__((format(printf, 2, 3)));
350 
351 /*!
352  * Log configuration fatal error
353  *
354  * \param Obj Object
355  * \param Msg Printf formatted message string
356  */
357 TEMU_API void temu_logConfigFatal(const void *Obj, const char *Msg, ...)
358  __attribute__((noreturn)) __attribute__((format(printf, 2, 3)));
359 
360 /*!
361  * Log configuration error
362  *
363  * \param Obj Object
364  * \param Msg Printf formatted message string
365  */
366 TEMU_API void temu_logConfigError(const void *Obj, const char *Msg, ...)
367  __attribute__((format(printf, 2, 3)));
368 
369 /*!
370  * Log configuration warning
371  *
372  * \param Obj Object
373  * \param Msg Printf formatted message string
374  */
375 TEMU_API void temu_logConfigWarning(const void *Obj, const char *Msg, ...)
376  __attribute__((format(printf, 2, 3)));
377 
378 /*!
379  * Log configuration info
380  *
381  * \param Obj Object
382  * \param Msg Printf formatted message string
383  */
384 
385 TEMU_API void temu_logConfigInfo(const void *Obj, const char *Msg, ...)
386  __attribute__((format(printf, 2, 3)));
387 
388 /*!
389  * Get object specific logging level for category
390  *
391  * \param Obj Object
392  * \param Category Category
393  * \result Logging level for the given `Category`
394  */
395 TEMU_API temu_LogLevel temu_objectGetLogLevel(void *Obj, unsigned Category);
396 /*!
397  * Set object specific logging level for category
398  *
399  * \param Obj Object
400  * \param Category Category
401  * \param LogLevel Level to set for the given `Category`
402  */
403 TEMU_API void temu_objectSetLogLevel(void *Obj, unsigned Category,
405 
406 #ifdef __cplusplus
407 }
408 #endif
409 
410 #endif /* ! TEMU_LOGGING_H */
teLL_Debug
@ teLL_Debug
Debug.
Definition: Logging.h:69
temu_logSetAdvancedFunc
TEMU_API void temu_logSetAdvancedFunc(void(*LogFunc)(void *, temu_Object *, unsigned, temu_LogLevel, const char *), void *UserData)
temu_logToCategory
TEMU_API void temu_logToCategory(const void *Obj, unsigned Category, temu_LogLevel Severity, const char *Msg,...) __attribute__((format(printf
temu_logConfigInfo
TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void temu_logConfigInfo(const void *Obj, const char *Msg,...) __attribute__((format(printf
teLL_Fatal
@ teLL_Fatal
Fatal, emulator cannot keep on running.
Definition: Logging.h:64
temu_logTargetError
TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void temu_logTargetError(const void *Obj, const char *Msg,...) __attribute__((format(printf
teLL_Info
@ teLL_Info
Normal messages.
Definition: Logging.h:67
teLL_Trace
@ teLL_Trace
Trace messages, not compiled away.
Definition: Logging.h:68
temu_logFatal
TEMU_API void temu_logFatal(const void *Obj, const char *Msg,...) __attribute__((noreturn)) __attribute__((format(printf
temu_logSetDefaultFile
TEMU_API void temu_logSetDefaultFile(FILE *FP)
temu_objectSetLogLevel
TEMU_API void temu_objectSetLogLevel(void *Obj, unsigned Category, temu_LogLevel LogLevel)
temu_logTargetInfo
TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void temu_logTargetInfo(const void *Obj, const char *Msg,...) __attribute__((format(printf
temu_logInfo
TEMU_API void TEMU_API void TEMU_API void TEMU_API void temu_logInfo(const void *Obj, const char *Msg,...) __attribute__((format(printf
temu_logWarning
TEMU_API void TEMU_API void TEMU_API void temu_logWarning(const void *Obj, const char *Msg,...) __attribute__((format(printf
temu_logSetLevel
TEMU_API void temu_logSetLevel(temu_LogLevel LogLevel)
temu_logDebugFunc
TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void temu_logDebugFunc(const void *Obj, const char *Msg,...) __attribute__((format(printf
temu_logSimError
TEMU_API void TEMU_API void TEMU_API void temu_logSimError(const void *Obj, const char *Msg,...) __attribute__((format(printf
temu_logConfigWarning
TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void temu_logConfigWarning(const void *Obj, const char *Msg,...) __attribute__((format(printf
temu_logSetFunc
TEMU_API void temu_logSetFunc(void(*LogFunc)(const char *))
teLL_Warning
@ teLL_Warning
Warnings.
Definition: Logging.h:66
temu_logTargetFatal
TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void temu_logTargetFatal(const void *Obj, const char *Msg,...) __attribute__((noreturn)) __attribute__((format(printf
temu_logTrace
TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void temu_logTrace(const void *Obj, const char *Msg,...) __attribute__((format(printf
temu_logSimInfo
TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void temu_logSimInfo(const void *Obj, const char *Msg,...) __attribute__((format(printf
temu_logSetSeverity
TEMU_API void temu_logSetSeverity(void *Obj, unsigned Category, temu_LogLevel Severity)
teLL_Error
@ teLL_Error
Error happened, in principle critical but up to user.
Definition: Logging.h:65
temu_logTargetWarning
TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void temu_logTargetWarning(const void *Obj, const char *Msg,...) __attribute__((format(printf
temu_logError
TEMU_API void TEMU_API void temu_logError(const void *Obj, const char *Msg,...) __attribute__((format(printf
temu_LogLevel
temu_LogLevel
Definition: Logging.h:63
temu_logConfigError
TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void temu_logConfigError(const void *Obj, const char *Msg,...) __attribute__((format(printf
temu_logSetColour
TEMU_API void temu_logSetColour(int Enable)
temu_logSimWarning
TEMU_API void TEMU_API void TEMU_API void TEMU_API void temu_logSimWarning(const void *Obj, const char *Msg,...) __attribute__((format(printf
temu_logSimFatal
TEMU_API void TEMU_API void temu_logSimFatal(const void *Obj, const char *Msg,...) __attribute__((noreturn)) __attribute__((format(printf
temu_logToCategoryVA
TEMU_API void temu_logToCategoryVA(const void *Obj, unsigned Category, temu_LogLevel Severity, const char *Msg, va_list Args)
temu_logConfigFatal
TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void TEMU_API void temu_logConfigFatal(const void *Obj, const char *Msg,...) __attribute__((noreturn)) __attribute__((format(printf