X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/dff9e15c44ab6340d27215957c56fa72fad246a2..9a444de20a7545d1c3d10bd242f317febded25c4:/src/xbt/xbt_log_layout_format.c diff --git a/src/xbt/xbt_log_layout_format.c b/src/xbt/xbt_log_layout_format.c index 993640082b..d8d39e03ca 100644 --- a/src/xbt/xbt_log_layout_format.c +++ b/src/xbt/xbt_log_layout_format.c @@ -1,8 +1,7 @@ -/* $Id$ */ - /* layout_simple - a dumb log layout */ -/* Copyright (c) 2003, 2004 Martin Quinson. All rights reserved. */ +/* Copyright (c) 2007-2011. The SimGrid Team. + * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -15,27 +14,9 @@ #include "xbt/synchro.h" /* xbt_thread_self_name */ #include -extern const char *xbt_log_priority_names[7]; - -static double begin_of_time = -1; +extern const char *xbt_log_priority_names[8]; -#define append1(fmt,fmt2,elm) \ - do { \ - if (precision == -1) { \ - xbt_strbuff_append(buff, tmp=bprintf(fmt,elm)); \ - free(tmp); \ - } else { \ - xbt_strbuff_append(buff, tmp=bprintf(fmt2,precision,elm)); \ - free(tmp); \ - precision = -1; \ - } \ - } while (0) -#define append2(fmt,elm,elm2) \ - do { \ - xbt_strbuff_append(buff, tmp=bprintf(fmt,elm,elm2)); \ - free(tmp); \ - precision = -1; \ - } while (0) +static double format_begin_of_time = -1; #define ERRMSG "Unknown %%%c sequence in layout format (%s).\nKnown sequences:\n" \ " what: %%m: user message %%c: log category %%p: log priority\n" \ @@ -46,147 +27,49 @@ static double begin_of_time = -1; " when: %%d: date %%r: app. age\n" \ " other: %%%%: %% %%n: new line %%e: plain space\n" +#define XBT_LOG_BUFF_SIZE (ev->buffer_size) -static void xbt_log_layout_format_dynamic(xbt_log_layout_t l, - xbt_log_event_t ev, - const char *fmt, - xbt_log_appender_t app) -{ - xbt_strbuff_t buff = xbt_strbuff_new(); - int precision = -1; - char *q = l->data; - char *tmp; - char *tmp2; - int vres; /* shut gcc up, but ignored */ - - while (*q != '\0') { - if (*q == '%') { - q++; - handle_modifier: - switch (*q) { - case '\0': - fprintf(stderr, "Layout format (%s) ending with %%\n", - (char *) l->data); - abort(); - case '%': - xbt_strbuff_append(buff, "%"); - break; - case 'n': /* platform-dependant line separator (LOG4J compliant) */ - xbt_strbuff_append(buff, "\n"); - break; - case 'e': /* plain space (SimGrid extension) */ - xbt_strbuff_append(buff, " "); - break; - - case '.': /* precision specifyier */ - q++; - q += sscanf(q, "%d", &precision); - goto handle_modifier; - - case 'c': /* category name; LOG4J compliant - should accept a precision postfix to show the hierarchy */ - append1("%s", "%.*s", ev->cat->name); - break; - case 'p': /* priority name; LOG4J compliant */ - append1("%s", "%.*s", xbt_log_priority_names[ev->priority]); - break; - - case 'h': /* host name; SimGrid extension */ - append1("%s", "%.*s", gras_os_myname()); - break; - case 't': /* thread name; LOG4J compliant */ - append1("%s", "%.*s", xbt_thread_self_name()); - break; - case 'P': /* process name; SimGrid extension */ - append1("%s", "%.*s", xbt_procname()); - break; - case 'i': /* process PID name; SimGrid extension */ - append1("%d", "%.*d", (*xbt_getpid) ()); - break; - - case 'F': /* file name; LOG4J compliant */ - append1("%s", "%.*s", ev->fileName); - break; - case 'l': /* location; LOG4J compliant */ - append2("%s:%d", ev->fileName, ev->lineNum); - precision = -1; /* Ignored */ - break; - case 'L': /* line number; LOG4J compliant */ - append1("%d", "%.*d", ev->lineNum); - break; - case 'M': /* method (ie, function) name; LOG4J compliant */ - append1("%s", "%.*s", ev->functionName); - break; - case 'b': /* backtrace; called %throwable in LOG4J */ - case 'B': /* short backtrace; called %throwable{short} in LOG4J */ -#if defined(HAVE_EXECINFO_H) && defined(HAVE_POPEN) && defined(ADDR2LINE) - { - xbt_ex_t e; - int i; - - e.used = backtrace((void **) e.bt, XBT_BACKTRACE_SIZE); - e.bt_strings = NULL; - e.msg = NULL; - e.remote = 0; - xbt_backtrace_current(&e); - if (*q == 'B') { - append1("%s", "%.*s", e.bt_strings[2] + 8); - } else { - for (i = 2; i < e.used; i++) - append1("%s\n", "%.*s\n", e.bt_strings[i] + 8); - } - - xbt_ex_free(e); - } -#else - append1("%s", "%.*s", "(no backtrace on this arch)"); -#endif - break; - - case 'd': /* date; LOG4J compliant */ - append1("%f", "%.*f", gras_os_time()); - break; - case 'r': /* application age; LOG4J compliant */ - append1("%f", "%.*f", gras_os_time() - begin_of_time); - break; - - case 'm': /* user-provided message; LOG4J compliant */ - vres = vasprintf(&tmp2, fmt, ev->ap_copy); - append1("%s", "%.*s", tmp2); - free(tmp2); - break; +#undef check_overflow +#define check_overflow \ + if (p - ev->buffer >= XBT_LOG_BUFF_SIZE) { /* buffer overflow */ \ + return 0; \ + } else ((void)0) + +#define show_it(data,letter) \ + do { \ + if (precision == -1 && length == -1) { \ + p += snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%" letter, data); \ + } else if (precision == -1) { \ + sprintf(tmpfmt,"%%%d" letter,length); \ + p += snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), tmpfmt, data); \ + length = -1; \ + } else if (length == -1) { \ + p += sprintf(p, "%.*" letter, \ + (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), precision), \ + data);\ + precision = -1; \ + } else { \ + sprintf(tmpfmt,"%%%d.%d" letter,length, \ + (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), precision));\ + p += sprintf(p, tmpfmt, data);\ + length = precision = -1; \ + } \ + check_overflow; \ + } while (0) - default: - fprintf(stderr, ERRMSG, *q, (char *) l->data); - abort(); - } - q++; - } else { - char tmp2[2]; - tmp2[0] = *(q++); - tmp2[1] = '\0'; - xbt_strbuff_append(buff, tmp2); - } - } - app->do_append(app, buff->data); - xbt_strbuff_free(buff); -} +#define show_string(data) show_it(data, "s") +#define show_int(data) show_it(data, "d") +#define show_double(data) show_it(data, "f") -#define check_overflow \ - if (p-ev->buffer > XBT_LOG_BUFF_SIZE) { /* buffer overflow */ \ - xbt_log_layout_format_dynamic(l,ev,msg_fmt,app); \ - return;\ - } -static void xbt_log_layout_format_doit(xbt_log_layout_t l, - xbt_log_event_t ev, - const char *msg_fmt, - xbt_log_appender_t app) +static int xbt_log_layout_format_doit(xbt_log_layout_t l, + xbt_log_event_t ev, + const char *msg_fmt) { char *p, *q; + char tmpfmt[50]; int precision = -1; + int length = -1; - if (begin_of_time < 0) - begin_of_time = gras_os_time(); p = ev->buffer; q = l->data; @@ -214,163 +97,67 @@ static void xbt_log_layout_format_doit(xbt_log_layout_t l, case '.': /* precision specifyier */ q++; - q += sscanf(q, "%d", &precision); + sscanf(q, "%d", &precision); + q += (precision>9?2:1); + goto handle_modifier; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': /* length modifier */ + sscanf(q, "%d", &length); + q += (length>9?2:1); goto handle_modifier; case 'c': /* category name; LOG4J compliant should accept a precision postfix to show the hierarchy */ - if (precision == -1) { - p += - snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%s", - ev->cat->name); - check_overflow; - } else { - p += - sprintf(p, "%.*s", - (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), - precision), ev->cat->name); - check_overflow; - precision = -1; - } + show_string(ev->cat->name); break; case 'p': /* priority name; LOG4J compliant */ - if (precision == -1) { - p += - snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%s", - xbt_log_priority_names[ev->priority]); - check_overflow; - } else { - p += - sprintf(p, "%.*s", - (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), - precision), - xbt_log_priority_names[ev->priority]); - check_overflow; - precision = -1; - } + show_string(xbt_log_priority_names[ev->priority]); break; case 'h': /* host name; SimGrid extension */ - if (precision == -1) { - p += - snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%s", - gras_os_myname()); - check_overflow; - } else { - p += - sprintf(p, "%.*s", - (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), - precision), gras_os_myname()); - check_overflow; - precision = -1; - } + show_string(gras_os_myname()); break; case 't': /* thread name; LOG4J compliant */ - if (precision == -1) { - p += - snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%s", - xbt_thread_self_name()); - check_overflow; - } else { - p += - sprintf(p, "%.*s", - (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), - precision), xbt_thread_self_name()); - check_overflow; - precision = -1; - } + show_string(xbt_thread_self_name()); break; case 'P': /* process name; SimGrid extension */ - if (precision == -1) { - p += - snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%s", - xbt_procname()); - check_overflow; - } else { - p += - sprintf(p, "%.*s", - (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), - precision), xbt_procname()); - check_overflow; - precision = -1; - } + show_string(xbt_procname()); break; case 'i': /* process PID name; SimGrid extension */ - if (precision == -1) { - p += - snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%d", - (*xbt_getpid) ()); - check_overflow; - } else { - p += - sprintf(p, "%.*d", - (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), - precision), (*xbt_getpid) ()); - check_overflow; - precision = -1; - } + show_int((*xbt_getpid) ()); break; case 'F': /* file name; LOG4J compliant */ - if (precision == -1) { - p += - snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%s", - ev->fileName); - check_overflow; - } else { - p += - sprintf(p, "%.*s", - (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), - precision), ev->fileName); - check_overflow; - precision = -1; - } + show_string(ev->fileName); break; case 'l': /* location; LOG4J compliant */ if (precision == -1) { - p += - snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%s:%d", - ev->fileName, ev->lineNum); + p += snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%s:%d", + ev->fileName, ev->lineNum); check_overflow; } else { - p += - snprintf(p, - (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), - precision), "%s:%d", ev->fileName, - ev->lineNum); + p += snprintf(p, + (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), + precision), "%s:%d", ev->fileName, + ev->lineNum); check_overflow; precision = -1; } break; case 'L': /* line number; LOG4J compliant */ - if (precision == -1) { - p += - snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%d", - ev->lineNum); - check_overflow; - } else { - p += - sprintf(p, "%.*d", - (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), - precision), ev->lineNum); - check_overflow; - precision = -1; - } + show_int(ev->lineNum); break; case 'M': /* method (ie, function) name; LOG4J compliant */ - if (precision == -1) { - p += - snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%s", - ev->functionName); - check_overflow; - } else { - p += - sprintf(p, "%.*s", - (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), - precision), ev->functionName); - check_overflow; - precision = -1; - } + show_string(ev->functionName); break; case 'b': /* backtrace; called %throwable in LOG4J */ case 'B': /* short backtrace; called %throwable{short} in LOG4J */ @@ -385,31 +172,18 @@ static void xbt_log_layout_format_doit(xbt_log_layout_t l, e.remote = 0; xbt_backtrace_current(&e); if (*q == 'B') { - if (precision == -1) { - p += - snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%s", - e.bt_strings[2] + 8); - check_overflow; - } else { - p += - sprintf(p, "%.*s", - (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), - precision), e.bt_strings[2] + 8); - check_overflow; - precision = -1; - } + show_string(e.bt_strings[2] + 8); } else { for (i = 2; i < e.used; i++) if (precision == -1) { - p += - snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%s\n", - e.bt_strings[i] + 8); + p += snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), + "%s\n", e.bt_strings[i] + 8); check_overflow; } else { - p += - sprintf(p, "%.*s\n", - (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), - precision), e.bt_strings[i] + 8); + p += sprintf(p, "%.*s\n", + (int) MIN(XBT_LOG_BUFF_SIZE - + (p - ev->buffer), precision), + e.bt_strings[i] + 8); check_overflow; precision = -1; } @@ -418,55 +192,28 @@ static void xbt_log_layout_format_doit(xbt_log_layout_t l, xbt_ex_free(e); } #else - p += - snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), - "(no backtrace on this arch)"); + p += snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), + "(no backtrace on this arch)"); check_overflow; #endif break; case 'd': /* date; LOG4J compliant */ - if (precision == -1) { - p += - snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%f", - gras_os_time()); - check_overflow; - } else { - p += - sprintf(p, "%.*f", - (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), - precision), gras_os_time()); - check_overflow; - precision = -1; - } + show_double(gras_os_time()); break; case 'r': /* application age; LOG4J compliant */ - if (precision == -1) { - p += - snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%f", - gras_os_time() - begin_of_time); - check_overflow; - } else { - p += - sprintf(p, "%.*f", - (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), - precision), gras_os_time() - begin_of_time); - check_overflow; - precision = -1; - } + show_double(gras_os_time() - format_begin_of_time); break; case 'm': /* user-provided message; LOG4J compliant */ if (precision == -1) { - p += - vsnprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), msg_fmt, - ev->ap); + p += vsnprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), msg_fmt, + ev->ap); check_overflow; } else { - p += - vsnprintf(p, - (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), - precision), msg_fmt, ev->ap); + p += vsnprintf(p, + (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), + precision), msg_fmt, ev->ap); check_overflow; precision = -1; } @@ -483,7 +230,8 @@ static void xbt_log_layout_format_doit(xbt_log_layout_t l, } } *p = '\0'; - app->do_append(app, ev->buffer); + + return 1; } static void xbt_log_layout_format_free(xbt_log_layout_t lay) @@ -497,5 +245,9 @@ xbt_log_layout_t xbt_log_layout_format_new(char *arg) res->do_layout = xbt_log_layout_format_doit; res->free_ = xbt_log_layout_format_free; res->data = xbt_strdup((char *) arg); + + if (format_begin_of_time < 0) + format_begin_of_time = gras_os_time(); + return res; }