1 //! Output string routines for Flog
3 //! @file flog_string.c
4 //! @author Nabeel Sowan (nabeel.sowan@vibes.se)
6 //! To convert flog messages to strings
7 //! internal use only, or when creating flog output function
9 #include "flog_string.h"
11 #ifdef FLOG_CONFIG_STRING_OUTPUT
19 #ifdef FLOG_CONFIG_TIMESTAMP
23 //! Create a string with timestamp in ISO-format
25 //! @param[out] **strp string to set (NULL on error)
26 //! @param[in] ts timestamp
28 int flog_get_str_iso_timestamp(char **strp
, const FLOG_TIMESTAMP_T ts
)
31 #ifdef FLOG_CONFIG_TIMESTAMP_USEC
32 ts_tm
= *localtime(&ts
.tv_sec
);
33 if(asprintf(strp
,"%04d-%02d-%02d %02d:%02d:%02d.%06d", ts_tm
.tm_year
+1900, ts_tm
.tm_mon
+1, ts_tm
.tm_mday
, ts_tm
.tm_hour
, ts_tm
.tm_min
, ts_tm
.tm_sec
, (int)ts
.tv_usec
)==-1) {
34 #else //FLOG_CONFIG_TIMESTAMP_USEC
35 ts_tm
= *localtime(&ts
);
36 if(asprintf(strp
,"%04d-%02d-%02d %02d:%02d:%02d", ts_tm
.tm_year
+1900, ts_tm
.tm_mon
+1, ts_tm
.tm_mday
, ts_tm
.tm_hour
, ts_tm
.tm_min
, ts_tm
.tm_sec
)==-1) {
37 #endif //FLOG_CONFIG_TIMESTAMP_USEC
43 #endif //FLOG_CONFIG_TIMESTAMP
46 //! Create a string or NULL according to message type
48 //! @param[out] **strp string to set (NULL on error)
49 //! @param[in] type type of message
51 int flog_get_str_msg_type(char **strp
, const FLOG_MSG_TYPE_T type
)
57 if(!(*strp
=strdup("Critical")))
61 if(!(*strp
=strdup("Error")))
65 if(!(*strp
=strdup("Warning")))
69 if(!(*strp
=strdup("!")))
77 if(!(*strp
=strdup("Debug")))
81 if(!(*strp
=strdup("Deep debug")))
91 #ifdef FLOG_CONFIG_MSG_ID_STRINGS
92 extern const char *flog_msg_id_str
[];
93 #endif //FLOG_CONFIG_MSG_ID_STRINGS
96 //! Create a string from FLOG_MSG_ID
98 //! @param[out] **strp string to set (NULL on error)
99 //! @param[in] msg_id message ID type
100 //! @retval 0 success
101 int flog_get_str_msg_id(char **strp
, const FLOG_MSG_ID_T msg_id
)
106 if(msg_id
>=FLOG_MSG_ID_AMOUNT_RESERVED_FOR_ERRNO
) {
107 #ifdef FLOG_CONFIG_MSG_ID_STRINGS
108 //! @todo we need to run toupper() on the first char of the message (maybe another function?)
109 #ifdef FLOG_CONFIG_OUTPUT_SHOW_MSG_ID
110 if(asprintf(strp
,"(%d) %s", msg_id
, flog_msg_id_str
[msg_id
-FLOG_MSG_ID_AMOUNT_RESERVED_FOR_ERRNO
])==-1) {
112 #else //FLOG_CONFIG_OUTPUT_SHOW_MSG_ID
113 if(!(*strp
=strdup(flog_msg_id_str
[msg_id
-FLOG_MSG_ID_AMOUNT_RESERVED_FOR_ERRNO
]))) {
114 #endif //FLOG_CONFIG_OUTPUT_SHOW_MSG_ID
115 #else //FLOG_CONFIG_MSG_ID_STRINGS
116 if(asprintf(strp
,"%d", msg_id
)==-1) {
118 #endif //FLOG_CONFIG_MSG_ID_STRINGS
122 //! @todo make thread safe with strerror_r()
123 #ifdef FLOG_CONFIG_ERRNO_STRINGS
124 #ifdef FLOG_CONFIG_OUTPUT_SHOW_MSG_ID
125 if(asprintf(strp
,"(%d) %s", msg_id
, strerror(msg_id
))==-1) {
127 #else //FLOG_CONFIG_OUTPUT_SHOW_MSG_ID
128 if(!(*strp
=strdup(strerror(msg_id
)))) {
129 #endif //FLOG_CONFIG_OUTPUT_SHOW_MSG_ID
130 #else //FLOG_CONFIG_ERRNO_STRINGS
131 if(asprintf(strp
,"(%d)", msg_id
)==-1) {
133 #endif //FLOG_CONFIG_ERRNO_STRINGS
141 #ifdef FLOG_CONFIG_SRC_INFO
142 //! Create a string from flog source info
144 //! @param[out] **strp string to set (NULL on error)
145 //! @param[in] *src_file source file
146 //! @param[in] src_line source line
147 //! @param[in] *src_func source function
148 //! @retval 0 success
149 int flog_get_str_src_info(char **strp
, const char *src_file
, const uint_fast16_t src_line
, const char *src_func
)
155 if(asprintf(strp
,"%s:%d|%s()",src_file
,(int)src_line
,src_func
)==-1) {
160 if(asprintf(strp
,"%s:%d",src_file
,(int)src_line
)==-1) {
167 if(asprintf(strp
,"%s|%s()",src_file
,src_func
)==-1) {
172 if(!(*strp
=strdup(src_file
)))
179 if(asprintf(strp
,":%d|%s()",(int)src_line
,src_func
)==-1) {
184 if(asprintf(strp
,":%d",(int)src_line
)==-1) {
191 if(asprintf(strp
,"%s()",src_func
)==-1) {
205 //! Create a string with message header
207 //! @param[out] **strp string to set (NULL on error)
208 //! @param[in] *p flog message type
209 //! @retval 0 success
210 int flog_get_str_message_header(char **strp
, const FLOG_MSG_T
*p
)
213 #ifdef FLOG_CONFIG_TIMESTAMP
215 if(flog_get_str_iso_timestamp(&str_timestamp
, p
->timestamp
))
218 #ifdef FLOG_CONFIG_SRC_INFO
220 if(flog_get_str_src_info(&str_src_info
, p
->src_file
, p
->src_line
, p
->src_func
)) {
221 #ifdef FLOG_CONFIG_TIMESTAMP
229 #ifdef FLOG_CONFIG_SRC_INFO
231 #ifdef FLOG_CONFIG_TIMESTAMP
233 if(asprintf(strp
,"%s %s %s", str_timestamp
, str_src_info
, p
->subsystem
)==-1) {
242 if(asprintf(strp
,"%s %s", str_src_info
, p
->subsystem
)==-1) {
247 #ifdef FLOG_CONFIG_TIMESTAMP
253 #ifdef FLOG_CONFIG_TIMESTAMP
255 if(asprintf(strp
,"%s %s", str_timestamp
, p
->subsystem
)==-1) {
263 if(!(*strp
=strdup(p
->subsystem
)))
265 #ifdef FLOG_CONFIG_TIMESTAMP
268 #ifdef FLOG_CONFIG_SRC_INFO
272 #ifdef FLOG_CONFIG_SRC_INFO
274 #ifdef FLOG_CONFIG_TIMESTAMP
276 if(asprintf(strp
,"%s %s", str_timestamp
, str_src_info
)==-1) {
285 if(!(*strp
=strdup(str_src_info
))) {
289 #ifdef FLOG_CONFIG_TIMESTAMP
295 #ifdef FLOG_CONFIG_TIMESTAMP
297 if(!(*strp
=strdup(str_timestamp
))) {
305 #ifdef FLOG_CONFIG_TIMESTAMP
308 #ifdef FLOG_CONFIG_SRC_INFO
316 //! Create a string with message contents
318 //! @param[out] **strp string to set (NULL on error)
319 //! @param[in] type type of message
320 //! @param[in] msg_id msg ID
321 //! @param[in] *text custom message string
322 //! @retval 0 success
323 int flog_get_str_message_content(char **strp
, const FLOG_MSG_TYPE_T type
, const FLOG_MSG_ID_T msg_id
, const char *text
)
325 char *str_type
,*str_msg_id
;
327 if(flog_get_str_msg_type(&str_type
,type
))
329 if(flog_get_str_msg_id(&str_msg_id
,msg_id
)) {
336 if(asprintf(strp
,"%s: %s: %s",str_type
,str_msg_id
,text
)==-1) {
343 if(asprintf(strp
,"%s: %s",str_type
,str_msg_id
)==-1) {
353 if(asprintf(strp
,"%s: %s",str_type
,text
)==-1) {
359 if(!(*strp
=strdup(str_type
))) {
369 if(asprintf(strp
,"%s: %s",str_msg_id
,text
)==-1) {
375 if(!(*strp
=strdup(str_msg_id
))) {
383 if(!(*strp
=strdup(text
)))
393 //! Create and return a string from FLOG_MSG_T type
395 //! @param[out] **strp string to set (NULL on error)
396 //! @param[in] *p flog message struct
397 //! @retval 0 success
398 int flog_get_str_message(char **strp
, const FLOG_MSG_T
*p
)
400 char *str_msg_header
, *str_msg_content
;
402 if(flog_get_str_message_header(&str_msg_header
,p
))
404 if(flog_get_str_message_content(&str_msg_content
, p
->type
, p
->msg_id
, p
->text
)) {
405 free(str_msg_header
);
409 if(str_msg_content
) {
410 if(asprintf(strp
,"[%s] %s\n", str_msg_header
, str_msg_content
)==-1) {
411 free(str_msg_content
);
412 free(str_msg_header
);
416 free(str_msg_content
);
418 if(asprintf(strp
,"[%s]\n", str_msg_header
)==-1) {
419 free(str_msg_header
);
424 free(str_msg_header
);
426 if(str_msg_content
) {
427 if(asprintf(strp
,"%s\n", str_msg_content
)==-1) {
428 free(str_msg_content
);
432 free(str_msg_content
);
441 char * flog_msg_t_to_str(const FLOG_MSG_T *p)
444 typestr=flog_get_msg_type_str(p->type);
445 #ifdef FLOG_CONFIG_TIMESTAMP
446 //! @todo add timestamp support
448 #ifdef FLOG_CONFIG_SRC_INFO
449 if((p->subsystem != NULL) && (typestr != NULL))
450 asprintf(&str,"[%s:%d|%s() %s] %s%s\n",p->src_file,(int)p->src_line,p->src_func,p->subsystem,typestr,p->text);
451 else if((p->subsystem != NULL) && (typestr == NULL))
452 asprintf(&str,"[%s:%d|%s() %s] %s\n",p->src_file,(int)p->src_line,p->src_func,p->subsystem,p->text);
453 else if((p->subsystem == NULL) && (typestr != NULL))
454 asprintf(&str,"[%s:%d|%s()] %s%s\n",p->src_file,(int)p->src_line,p->src_func,typestr,p->text);
456 asprintf(&str,"[%s:%d|%s()] %s\n",p->src_file,(int)p->src_line,p->src_func,p->text);
458 if((p->subsystem != NULL) && (typestr != NULL))
459 asprintf(&str,"[%s] %s%s\n",p->subsystem,typestr,p->text);
460 else if((p->subsystem != NULL) && (typestr == NULL))
461 asprintf(&str,"[%s] %s\n",p->subsystem,p->text);
462 else if((p->subsystem == NULL) && (typestr != NULL))
463 asprintf(&str,"%s%s\n",typestr,p->text);
465 asprintf(&str,"%s\n",p->text);
466 #endif //FLOG_CONFIG_SRC_INFO
467 #endif //FLOG_CONFIG_TIMESTAMP
473 #endif //FLOG_CONFIG_STRING_OUTPUT