Line data Source code
1 : /** @file assert.c
2 : * @brief Compiled functions used by debugging macros to write on stderr
3 : * @date 11/05/1997
4 : * @author François Cerbelle (Fanfan), francois@cerbelle.net
5 : * @copyright Copyright (c) 1997-2024, François Cerbelle
6 : *
7 : * Originally inspired by "L'art du code", Steve Maguire, Microsoft Press
8 : *
9 : * @internal
10 : * Compiler gcc
11 : * Last modified 2024-12-19 19:49
12 : * Organization Cerbelle.net
13 : * Company Home
14 : *
15 : * This source code is released for free distribution under the terms of the
16 : * GNU General Public License as published by the Free Software Foundation.
17 : *
18 : */
19 :
20 : #define _XOPEN_SOURCE 500 /* vasprintf */
21 : #include "libdebug/assert.h"
22 : #include <stdarg.h> /* va_list, va_start, va_arg, va_end */
23 : #include <string.h> /* strcpy */
24 : #include <stdio.h> /* fprintf */
25 : #include <time.h> /* time, localtime */
26 : #include <stdlib.h> /* abort */
27 : #include <stdio.h> /* snprintf */
28 :
29 : /** Build a timestamp string with filename and compilation date
30 : *
31 : * Returned value is a static string which can be modified later. It should not
32 : * be passed to free and should not be modified.
33 : *
34 : * NULL or empty string parameter values will abort the program.
35 : *
36 : * @param[in] p_File Source file
37 : * @param[in] p_Line Source line in the source file
38 : * @param[in] p_CompilDate Compilation date
39 : * @param[in] p_CompilTime Compilation time
40 : * @param[in] p_Function Function name in the source file
41 : *
42 : * @return Pointer to a static string
43 : */
44 197 : static const char*_timestamp(const char* p_File,
45 : const unsigned int p_Line,
46 : const char* p_CompilDate,
47 : const char* p_CompilTime,
48 : const char* p_Function) {
49 : /* Get local time and format it */
50 : char l_Time[24];
51 : static char l_tmp[120];
52 197 : time_t l_CurrentTime = time(NULL);
53 :
54 : /* Parameter validity check against invalid parameters such as NULL or
55 : * empty string values. */
56 197 : if ((NULL==p_File)|| (0==p_File[0])||
57 179 : (0==p_Line)||
58 173 : (NULL==p_CompilDate)|| (0==p_CompilDate[0])||
59 161 : (NULL==p_CompilTime)|| (0==p_CompilTime[0])||
60 145 : (NULL==p_Function)|| (0==p_Function[0])) {
61 58 : fprintf(stderr,"%s:%d Unexpected and invalid parameters\n",__FILE__, __LINE__);
62 58 : abort();
63 : }
64 :
65 139 : strftime(l_Time, sizeof(l_Time), "%Y-%m-%d %H:%M:%S", localtime(&l_CurrentTime));
66 :
67 : /* Timestamp build with the filename, file line, function name */
68 : /** @todo Replace with a portable snprintf function */
69 139 : snprintf(l_tmp,sizeof(l_tmp),
70 : "%19s [%20s:%-4ud] (%11s @ %8s) %30s()",
71 : l_Time,p_File,p_Line,p_CompilDate,p_CompilTime,p_Function /* cppcheck-suppress ctunullpointer */
72 : );
73 139 : return &l_tmp[0];
74 : }
75 :
76 : /* Documentation in header file */
77 33 : void _trace(const char* p_File,
78 : const unsigned int p_Line,
79 : const char* p_CompilDate,
80 : const char* p_CompilTime, const char* p_Function) {
81 : /* Parameter validity enforced by _timestamp */
82 33 : fprintf (stderr,"%s\n",
83 : _timestamp( p_File, p_Line, p_CompilDate, p_CompilTime, p_Function)
84 : );
85 15 : }
86 :
87 : /* Documentation in header file */
88 50 : void _trace_msg(const char* p_File,
89 : const unsigned int p_Line,
90 : const char* p_CompilDate,
91 : const char* p_CompilTime,
92 : const char* p_Function, const char* p_Message) {
93 : /* Parameter validity enforced by _timestamp */
94 50 : fprintf (stderr,"%s : %s\n",
95 : _timestamp( p_File, p_Line, p_CompilDate, p_CompilTime, p_Function),
96 : p_Message /* cppcheck-suppress ctunullpointer */
97 : );
98 30 : }
99 :
100 : /* Documentation in header file */
101 114 : void _trace_dynmsg(const char* p_File,
102 : const unsigned int p_Line,
103 : const char* p_CompilDate,
104 : const char* p_CompilTime,
105 : const char* p_Function, const char* p_Format, ...
106 : ) {
107 : /* Formatted message string */
108 : char l_tmp[100];
109 : /* Formatted message length */
110 : unsigned int l_length;
111 :
112 : /* Limit variadic processing scope in a block */
113 : {
114 : /* Build the formatted message */
115 : va_list l_ap;
116 114 : va_start(l_ap, p_Format);
117 : /** @todo Replace with a portable snprintf function */
118 114 : l_length = vsnprintf(l_tmp,sizeof(l_tmp),p_Format,l_ap);
119 114 : va_end(l_ap);
120 : }
121 :
122 114 : if (l_length >= sizeof(l_tmp)-1) {
123 : /* Indicate that message was truncated */
124 68 : strcpy(&(l_tmp[sizeof(l_tmp)-6]),"[...]");
125 : }
126 :
127 : /* Parameter validity enforced by _timestamp */
128 114 : fprintf (stderr,"%s : %s\n",
129 : _timestamp( p_File, p_Line, p_CompilDate, p_CompilTime, p_Function),
130 : l_tmp
131 : );
132 94 : }
133 : /* vim: set tw=80: */
|