1 /* layout_simple - a dumb log layout */
3 /* Copyright (c) 2007-2019. The SimGrid Team. */
5 /* This program is free software; you can redistribute it and/or modify it
6 * under the terms of the license (GNU LGPL) which comes with this package. */
8 #include "simgrid/host.h"
9 #include "simgrid/msg.h" /* MSG_get_clock */
10 #include "src/xbt/log_private.h"
11 #include "xbt/sysdep.h"
15 #define MIN(a, b) ((a) < (b) ? (a) : (b))
18 #define MAX(a, b) ((a) > (b) ? (a) : (b))
21 extern const char *xbt_log_priority_names[8];
24 "Unknown %%%c sequence in layout format (%s).\n" \
25 "Known sequences:\n" \
26 " what: %%m: user message %%c: log category %%p: log priority\n" \
28 " source: %%F: file %%L: line %%M: function %%l: location (%%F:%%L)\n" \
29 " runtime: %%h: hostname %%t: thread %%P: process %%i: PID\n" \
30 " when: %%d: date %%r: app. age\n" \
31 " other: %%%%: %% %%n: new line %%e: plain space\n"
33 #define check_overflow(len) \
34 if ((rem_size -= (len)) > 0) { \
39 #define set_sz_from_precision() \
42 if (precision != -1) { \
44 sz = precision + 1; /* +1 for the final '\0' */ \
49 #define show_it(data, letter) \
59 if (precision == -1) { \
60 len = snprintf(p, rem_size, "%*" letter, wd, data); \
62 len = snprintf(p, rem_size, "%*.*" letter, wd, precision, data); \
65 check_overflow(len); \
68 #define show_string(data) \
70 const char *show_string_data = (data); \
71 show_it(show_string_data ? show_string_data : "(null)", "s"); \
73 #define show_int(data) show_it(data, "d")
74 #define show_double(data) show_it(data, "f")
76 static int xbt_log_layout_format_doit(xbt_log_layout_t l, xbt_log_event_t ev, const char *msg_fmt)
79 int rem_size = ev->buffer_size;
83 for (char* q = l->data ; *q != '\0' ; q++) {
89 fprintf(stderr, "Layout format (%s) ending with %%\n", (char*)l->data);
95 case 'n': /* platform-dependant line separator; LOG4J compliant */
99 case 'e': /* plain space; SimGrid extension */
103 case '.': /* precision specifier */
104 precision = strtol(q + 1, &q, 10);
105 continue; /* conversion specifier still not found, continue reading */
115 case '9': /* length modifier */
116 length = strtol(q, &q, 10);
117 continue; /* conversion specifier still not found, continue reading */
118 case 'c': /* category name; LOG4J compliant
119 should accept a precision postfix to show the hierarchy */
120 show_string(ev->cat->name);
122 case 'p': /* priority name; LOG4J compliant */
123 show_string(xbt_log_priority_names[ev->priority]);
125 case 'h': /* host name; SimGrid extension */
126 show_string(sg_host_self_get_name());
128 case 't': /* thread/process name; LOG4J compliant */
129 case 'P': /* process name; SimGrid extension */
130 show_string(xbt_procname());
132 case 'i': /* process PID name; SimGrid extension */
133 show_int(xbt_getpid());
135 case 'F': /* file name; LOG4J compliant */
136 show_string(ev->fileName);
138 case 'l': { /* location; LOG4J compliant */
140 set_sz_from_precision();
141 int len = snprintf(p, sz, "%s:%d", ev->fileName, ev->lineNum);
142 check_overflow(MIN(sz, len));
145 case 'L': /* line number; LOG4J compliant */
146 show_int(ev->lineNum);
148 case 'M': /* method (ie, function) name; LOG4J compliant */
149 show_string(ev->functionName);
151 case 'd': /* date; LOG4J compliant */
152 show_double(MSG_get_clock());
154 case 'r': /* application age; LOG4J compliant */
155 show_double(MSG_get_clock());
157 case 'm': { /* user-provided message; LOG4J compliant */
159 set_sz_from_precision();
162 int len = vsnprintf(p, sz, msg_fmt, ap);
164 check_overflow(MIN(sz, len));
168 fprintf(stderr, ERRMSG, *q, (char*)l->data);
171 break; /* done, continue normally */
183 static void xbt_log_layout_format_free(xbt_log_layout_t lay)
188 xbt_log_layout_t xbt_log_layout_format_new(char *arg)
190 xbt_log_layout_t res = xbt_new0(s_xbt_log_layout_t, 1);
191 res->do_layout = &xbt_log_layout_format_doit;
192 res->free_ = &xbt_log_layout_format_free;
193 res->data = xbt_strdup((char *) arg);