Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Now that there is some mallocated space in the category architectures (the layouts...
[simgrid.git] / src / xbt / xbt_log_layout_format.c
1 /* $Id$ */
2
3 /* layout_simple - a dumb log layout                                        */
4
5 /* Copyright (c) 2003, 2004 Martin Quinson. All rights reserved.            */
6
7 /* This program is free software; you can redistribute it and/or modify it
8  * under the terms of the license (GNU LGPL) which comes with this package. */
9
10 #include "portable.h" /* execinfo when available */
11 #include "xbt/sysdep.h"
12 #include "xbt/log.h"
13 #include "gras/virtu.h"
14 #include <stdio.h>
15 #include "xbt/ex_interface.h" /* backtraces */
16
17 extern const char *xbt_log_priority_names[7];
18
19
20 static char *xbt_log_layout_format_doit(xbt_log_layout_t l,
21                                         xbt_log_event_t ev, 
22                                         const char *msg_fmt) {
23   static char res[2048];
24   static double begin_of_time = -1;
25   char *p,*q;  
26
27   if (begin_of_time<0) 
28     begin_of_time=gras_os_time();
29
30   p = res;
31   q = l->data;
32
33   while (*q != '\0') {
34     if (*q == '%') {
35       q++;
36       switch (*q) {
37       case '\0':
38         THROW1(arg_error,0,"Layout format (%s) ending with %%",(char*)l->data);
39       case '%':
40         *p++ = '%';
41         break;
42       case 'n': /* platform-dependant line separator (LOG4J compliant) */
43         p += sprintf(p,"\n");
44         break;
45       case ' ': /* plain space (SimGrid extension) */
46         p += sprintf(p," ");
47         break;
48
49       case 'c': /* category name; LOG4J compliant
50                    should accept a precision postfix to show the hierarchy */
51         p += sprintf(p,"%s",ev->cat->name); 
52         break;
53       case 'p': /* priority name; LOG4J compliant */    
54         p += sprintf(p, "%s", xbt_log_priority_names[ev->priority] );
55         break;
56
57       case 'h': /* host name; SimGrid extension */
58         p += sprintf(p, "%s", gras_os_myname());
59         break;
60       case 't': /* process name; LOG4J compliant (thread name) */
61         p += sprintf(p, "%s", xbt_procname());
62         break;
63       case 'i': /* process PID name; SimGrid extension */
64         p += sprintf(p, "%ld", gras_os_getpid());
65         break;
66
67       case 'F': /* file name; LOG4J compliant */
68         p += sprintf(p,"%s",ev->fileName);
69         break;
70       case 'l': /* location; LOG4J compliant */
71         p += sprintf(p, "%s:%d", ev->fileName, ev->lineNum);
72         break;
73       case 'L': /* line number; LOG4J compliant */
74         p += sprintf(p, "%d", ev->lineNum);
75         break;
76       case 'M': /* method (ie, function) name; LOG4J compliant */
77         p += sprintf(p, "%s", ev->functionName);
78         break;
79       case 'b': /* backtrace; called %throwable in LOG4J */
80       case 'B': /* short backtrace; called %throwable{short} in LOG4J */
81 #if defined(HAVE_EXECINFO_H) && defined(HAVE_POPEN) && defined(ADDR2LINE)
82         {
83           xbt_ex_t e;
84           int i;
85           
86           e.used     = backtrace((void**)e.bt,XBT_BACKTRACE_SIZE);
87           e.bt_strings = NULL;
88           xbt_ex_setup_backtrace(&e);
89           if (*q=='B')
90             p += sprintf(p,"%s",e.bt_strings[2]+8);
91           else
92             for (i=2; i<e.used; i++)
93               p += sprintf(p,"%s\n",e.bt_strings[i]+8);
94           
95           e.msg=NULL;
96           e.remote=0;
97           xbt_ex_free(e);
98         }
99 #else
100         p+=sprintf(p,"(no backtrace on this arch)");
101 #endif
102         break;
103
104       case 'd': /* date; LOG4J compliant */
105         p += sprintf(p,"%f", gras_os_time());
106         break;
107       case 'r': /* application age; LOG4J compliant */
108         p += sprintf(p,"%f", gras_os_time()-begin_of_time);
109         break;
110         
111       case 'm': /* user-provided message; LOG4J compliant */
112         p += vsprintf(p, msg_fmt, ev->ap);
113         break;
114
115       default:
116         THROW2(arg_error,0,"Unknown %%%c sequence in layout format (%s)",
117                *q,(char*)l->data);
118       }
119       q++;
120     } else {
121       *(p++) = *(q++);
122     }
123   }
124   *p = '\0';
125   return res;
126 }
127
128 static void xbt_log_layout_format_free(xbt_log_layout_t lay) {
129   free(lay->data);
130 }
131 xbt_log_layout_t xbt_log_layout_format_new(char *arg) {
132   xbt_log_layout_t res = xbt_new0(s_xbt_log_layout_t,1);
133   res->do_layout = xbt_log_layout_format_doit;
134   res->free_     = xbt_log_layout_format_free;
135   res->data = xbt_strdup((char*)arg);
136   return res;
137 }