Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
%P is now the process name, and %t becomes the thread name (as it should for complian...
[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 "xbt/synchro.h" /* xbt_thread_self */
15 #include <stdio.h>
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   int precision=-1;
27
28   if (begin_of_time<0) 
29     begin_of_time=gras_os_time();
30
31   p = res;
32   q = l->data;
33
34   while (*q != '\0') {
35     if (*q == '%') {
36       q++;
37        handle_modifier:
38       switch (*q) {
39       case '\0':
40         fprintf(stderr,"Layout format (%s) ending with %%\n",(char*)l->data);
41         abort();
42       case '%':
43         *p++ = '%';
44         break;
45       case 'n': /* platform-dependant line separator (LOG4J compliant) */
46         p += sprintf(p,"\n");
47         break;
48       case 'e': /* plain space (SimGrid extension) */
49         p += sprintf(p," ");
50         break;
51          
52       case '.': /* precision specifyier */
53         q++;
54         q += sscanf(q,"%d",&precision);
55         goto handle_modifier;
56
57       case 'c': /* category name; LOG4J compliant
58                    should accept a precision postfix to show the hierarchy */
59         if (precision == -1)
60            p += sprintf(p,"%s",ev->cat->name);
61         else {        
62            p += sprintf(p,"%.*s",precision,ev->cat->name);
63            precision = -1;
64         }        
65         break;
66       case 'p': /* priority name; LOG4J compliant */    
67         if (precision == -1)
68            p += sprintf(p, "%s", xbt_log_priority_names[ev->priority] );
69         else {        
70            p += sprintf(p, "%.*s", precision, xbt_log_priority_names[ev->priority] );
71            precision = -1;
72         }        
73         break;
74
75       case 'h': /* host name; SimGrid extension */
76         if (precision == -1)
77            p += sprintf(p, "%s", gras_os_myname());
78         else {        
79            p += sprintf(p, "%.*s", precision, gras_os_myname());
80            precision = -1;
81         }        
82         break;
83       case 't': /* thread name; LOG4J compliant */
84         p += sprintf(p, "%p", xbt_thread_self());
85         precision = -1;
86         break;
87       case 'P': /* process name; SimGrid extension */
88         if (precision == -1)
89            p += sprintf(p, "%s", xbt_procname());
90         else {        
91            p += sprintf(p, "%.*s", precision,xbt_procname());
92            precision = -1;
93         }        
94         break;
95       case 'i': /* process PID name; SimGrid extension */
96         if (precision == -1)
97            p += sprintf(p, "%d", (*xbt_getpid)());
98         else {        
99            p += sprintf(p, "%.*d", precision, (*xbt_getpid)());
100            precision = -1;
101         }        
102         break;
103
104       case 'F': /* file name; LOG4J compliant */
105         if (precision == -1)
106            p += sprintf(p,"%s",ev->fileName);
107         else {        
108            p += sprintf(p,"%.*s",precision, ev->fileName);
109            precision = -1;
110         }        
111         break;
112       case 'l': /* location; LOG4J compliant */
113         if (precision == -1)
114            p += sprintf(p, "%s:%d", ev->fileName, ev->lineNum);
115         else {        
116            p += snprintf(p, precision, "%s:%d", ev->fileName, ev->lineNum);
117            precision = -1;
118         }        
119         break;
120       case 'L': /* line number; LOG4J compliant */
121         if (precision == -1)
122            p += sprintf(p, "%d", ev->lineNum);
123         else {        
124            p += sprintf(p, "%.*d", precision, ev->lineNum);
125            precision = -1;
126         }        
127         break;
128       case 'M': /* method (ie, function) name; LOG4J compliant */
129         if (precision == -1)
130            p += sprintf(p, "%s", ev->functionName);
131         else {        
132            p += sprintf(p, "%.*s", precision, ev->functionName);
133            precision = -1;
134         }        
135         break;
136       case 'b': /* backtrace; called %throwable in LOG4J */
137       case 'B': /* short backtrace; called %throwable{short} in LOG4J */
138 #if defined(HAVE_EXECINFO_H) && defined(HAVE_POPEN) && defined(ADDR2LINE)
139         {
140           xbt_ex_t e;
141           int i;
142           
143           e.used     = backtrace((void**)e.bt,XBT_BACKTRACE_SIZE);
144           e.bt_strings = NULL;
145           e.msg=NULL;
146           e.remote=0;
147           xbt_backtrace_current(&e);
148           if (*q=='B') {
149              if (precision == -1)
150                p += sprintf(p,"%s",e.bt_strings[2]+8);
151              else {           
152                 p += sprintf(p,"%.*s",precision, e.bt_strings[2]+8);
153                 precision = -1;
154              }   
155           } else {
156             for (i=2; i<e.used; i++)
157                if (precision == -1)
158                  p += sprintf(p,"%s\n",e.bt_strings[i]+8);
159              else {           
160                  p += sprintf(p,"%.*s\n",precision,e.bt_strings[i]+8);
161                 precision = -1;
162              }   
163           }
164            
165           xbt_ex_free(e);
166         }
167 #else
168         p+=sprintf(p,"(no backtrace on this arch)");
169 #endif
170         break;
171
172       case 'd': /* date; LOG4J compliant */
173         if (precision == -1)
174            p += sprintf(p,"%f", gras_os_time());
175         else {        
176            p += sprintf(p,"%.*f", precision, gras_os_time());
177            precision = -1;
178         }        
179         break;
180       case 'r': /* application age; LOG4J compliant */
181         if (precision == -1)
182            p += sprintf(p,"%f", gras_os_time()-begin_of_time);
183         else {        
184            p += sprintf(p,"%.*f", precision, gras_os_time()-begin_of_time);
185            precision = -1;
186         }        
187         break;
188         
189       case 'm': /* user-provided message; LOG4J compliant */
190         if (precision == -1)
191            p += vsprintf(p, msg_fmt, ev->ap);
192         else {        
193            p += vsnprintf(p, precision, msg_fmt, ev->ap);
194            precision = -1;
195         }        
196         break;
197
198       default:
199         fprintf(stderr,"Unknown %%%c sequence in layout format (%s)\n",
200                 *q,(char*)l->data);
201         abort();
202       }
203       q++;
204     } else {
205       *(p++) = *(q++);
206     }
207   }
208   *p = '\0';
209   return res;
210 }
211
212 static void xbt_log_layout_format_free(xbt_log_layout_t lay) {
213   free(lay->data);
214 }
215 xbt_log_layout_t xbt_log_layout_format_new(char *arg) {
216   xbt_log_layout_t res = xbt_new0(s_xbt_log_layout_t,1);
217   res->do_layout = xbt_log_layout_format_doit;
218   res->free_     = xbt_log_layout_format_free;
219   res->data = xbt_strdup((char*)arg);
220   return res;
221 }