Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
properly protect our definitions of MIN/MAX (w/o using undef to please sonar)
[simgrid.git] / src / xbt / log.c
index a591421..7853627 100644 (file)
@@ -1,6 +1,6 @@
 /* log - a generic logging facility in the spirit of log4j                  */
 
-/* Copyright (c) 2004-2015. The SimGrid Team.
+/* Copyright (c) 2004-2018. The SimGrid Team.
  * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
 
 #include "src/xbt_modinter.h"
 
-#include "xbt/misc.h"
+#include "src/xbt/log_private.h"
+#include "xbt/asserts.h"
+#include "xbt/dynar.h"
 #include "xbt/ex.h"
+#include "xbt/misc.h"
 #include "xbt/str.h"
 #include "xbt/sysdep.h"
-#include "src/xbt/log_private.h"
-#include "xbt/dynar.h"
 #include "xbt/xbt_os_thread.h"
 
-int xbt_log_no_loc = 0;         /* if set to true (with --log=no_loc), file localization will be omitted (for tesh tests) */
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+int xbt_log_no_loc = 0; /* if set to true (with --log=no_loc), file localization will be omitted (for tesh tests) */
 static xbt_os_mutex_t log_cat_init_mutex = NULL;
 
 /** \addtogroup XBT_log
@@ -40,7 +48,9 @@ typedef struct {
   e_xbt_log_priority_t thresh;
   int additivity;
   xbt_log_appender_t appender;
-} s_xbt_log_setting_t, *xbt_log_setting_t;
+} s_xbt_log_setting_t;
+
+typedef s_xbt_log_setting_t* xbt_log_setting_t;
 
 static xbt_dynar_t xbt_log_settings = NULL;
 
@@ -89,171 +99,6 @@ void xbt_log_preinit(void)
   log_cat_init_mutex = xbt_os_mutex_init();
 }
 
-static void xbt_log_connect_categories(void)
-{
-  /* Connect our log channels: that must be done manually under windows */
-  /* Also permit that they are correctly listed by xbt_log_help_categories() */
-
-  /* xbt */
-  XBT_LOG_CONNECT(xbt);
-  XBT_LOG_CONNECT(log);
-  XBT_LOG_CONNECT(module);
-  XBT_LOG_CONNECT(replay);
-  XBT_LOG_CONNECT(strbuff);
-  XBT_LOG_CONNECT(xbt_cfg);
-  XBT_LOG_CONNECT(xbt_dict);
-  XBT_LOG_CONNECT(xbt_dict_cursor);
-  XBT_LOG_CONNECT(xbt_dict_elm);
-  XBT_LOG_CONNECT(xbt_dyn);
-  XBT_LOG_CONNECT(xbt_ex);
-  XBT_LOG_CONNECT(xbt_fifo);
-  XBT_LOG_CONNECT(xbt_graph);
-  XBT_LOG_CONNECT(xbt_heap);
-  XBT_LOG_CONNECT(xbt_lib);
-  XBT_LOG_CONNECT(xbt_mallocator);
-  XBT_LOG_CONNECT(xbt_matrix);
-  XBT_LOG_CONNECT(xbt_parmap);
-  XBT_LOG_CONNECT(xbt_sync);
-  XBT_LOG_CONNECT(xbt_sync_os);
-
-#ifdef simgrid_EXPORTS
-  /* The following categories are only defined in libsimgrid */
-
-  /* bindings */
-#if HAVE_LUA
-  XBT_LOG_CONNECT(lua);
-  XBT_LOG_CONNECT(lua_host);
-  XBT_LOG_CONNECT(lua_platf);
-  XBT_LOG_CONNECT(lua_debug);
-#endif
-
-  /* instr */
-  XBT_LOG_CONNECT(instr);
-  XBT_LOG_CONNECT(instr_api);
-  XBT_LOG_CONNECT(instr_config);
-  XBT_LOG_CONNECT(instr_msg);
-  XBT_LOG_CONNECT(instr_msg_process);
-  XBT_LOG_CONNECT(instr_msg_vm);
-  XBT_LOG_CONNECT(instr_paje_containers);
-  XBT_LOG_CONNECT(instr_paje_header);
-  XBT_LOG_CONNECT(instr_paje_trace);
-  XBT_LOG_CONNECT(instr_paje_types);
-  XBT_LOG_CONNECT(instr_paje_values);
-  XBT_LOG_CONNECT(instr_resource);
-  XBT_LOG_CONNECT(instr_routing);
-  XBT_LOG_CONNECT(instr_surf);
-  XBT_LOG_CONNECT(instr_trace);
-  XBT_LOG_CONNECT(instr_TI_trace);
-
-  /* jedule */
-#if HAVE_JEDULE
-  XBT_LOG_CONNECT(jedule);
-  XBT_LOG_CONNECT(jed_out);
-  XBT_LOG_CONNECT(jed_sd);
-#endif
-
-  /* mc */
-#if HAVE_MC
-  XBT_LOG_CONNECT(mc);
-  XBT_LOG_CONNECT(mc_checkpoint);
-  XBT_LOG_CONNECT(mc_comm_determinism);
-  XBT_LOG_CONNECT(mc_compare);
-  XBT_LOG_CONNECT(mc_dwarf);
-  XBT_LOG_CONNECT(mc_hash);
-  XBT_LOG_CONNECT(mc_liveness);
-  XBT_LOG_CONNECT(mc_memory);
-  XBT_LOG_CONNECT(mc_page_snapshot);
-  XBT_LOG_CONNECT(mc_request);
-  XBT_LOG_CONNECT(mc_safety);
-  XBT_LOG_CONNECT(mc_VisitedState);
-  XBT_LOG_CONNECT(mc_client);
-  XBT_LOG_CONNECT(mc_client_api);
-  XBT_LOG_CONNECT(mc_comm_pattern);
-  XBT_LOG_CONNECT(mc_process);
-  XBT_LOG_CONNECT(mc_protocol);
-  XBT_LOG_CONNECT(mc_RegionSnaphot);
-  XBT_LOG_CONNECT(mc_ModelChecker);
-  XBT_LOG_CONNECT(mc_state);
-#endif
-  XBT_LOG_CONNECT(mc_global);
-  XBT_LOG_CONNECT(mc_config);
-  XBT_LOG_CONNECT(mc_record);
-
-  /* msg */
-  XBT_LOG_CONNECT(msg);
-  XBT_LOG_CONNECT(msg_action);
-  XBT_LOG_CONNECT(msg_gos);
-  XBT_LOG_CONNECT(msg_io);
-  XBT_LOG_CONNECT(msg_kernel);
-  XBT_LOG_CONNECT(msg_mailbox);
-  XBT_LOG_CONNECT(msg_process);
-  XBT_LOG_CONNECT(msg_synchro);
-  XBT_LOG_CONNECT(msg_task);
-  XBT_LOG_CONNECT(msg_vm);
-
-  /* sg */
-  XBT_LOG_CONNECT(sg_host);
-
-  /* simdag */
-  XBT_LOG_CONNECT(sd);
-  XBT_LOG_CONNECT(sd_daxparse);
-#if HAVE_GRAPHVIZ
-  XBT_LOG_CONNECT(sd_dotparse);
-#endif
-  XBT_LOG_CONNECT(sd_kernel);
-  XBT_LOG_CONNECT(sd_task);
-
-  /* simix */
-  XBT_LOG_CONNECT(simix);
-  XBT_LOG_CONNECT(simix_context);
-  XBT_LOG_CONNECT(simix_deployment);
-  XBT_LOG_CONNECT(simix_environment);
-  XBT_LOG_CONNECT(simix_host);
-  XBT_LOG_CONNECT(simix_io);
-  XBT_LOG_CONNECT(simix_kernel);
-  XBT_LOG_CONNECT(simix_network);
-  XBT_LOG_CONNECT(simix_process);
-  XBT_LOG_CONNECT(simix_popping);
-  XBT_LOG_CONNECT(simix_synchro);
-  XBT_LOG_CONNECT(simix_vm);
-
-  /* smpi */
-  /* SMPI categories are connected in smpi_global.c */
-
-  /* surf */
-  XBT_LOG_CONNECT(surf);
-  XBT_LOG_CONNECT(surf_config);
-  XBT_LOG_CONNECT(surf_cpu);
-  XBT_LOG_CONNECT(surf_cpu_cas);
-  XBT_LOG_CONNECT(surf_cpu_ti);
-  XBT_LOG_CONNECT(surf_energy);
-  XBT_LOG_CONNECT(surf_kernel);
-  XBT_LOG_CONNECT(surf_lagrange);
-  XBT_LOG_CONNECT(surf_lagrange_dichotomy);
-  XBT_LOG_CONNECT(surf_maxmin);
-  XBT_LOG_CONNECT(surf_network);
-#if HAVE_NS3
-  XBT_LOG_CONNECT(ns3);
-#endif
-  XBT_LOG_CONNECT(surf_parse);
-  XBT_LOG_CONNECT(surf_route);
-  XBT_LOG_CONNECT(surf_routing_generic);
-  XBT_LOG_CONNECT(surf_route_cluster);
-  XBT_LOG_CONNECT(surf_route_cluster_torus);
-  XBT_LOG_CONNECT(surf_route_dijkstra);
-  XBT_LOG_CONNECT(surf_route_fat_tree);
-  XBT_LOG_CONNECT(surf_route_floyd);
-  XBT_LOG_CONNECT(surf_route_full);
-  XBT_LOG_CONNECT(surf_route_none);
-  XBT_LOG_CONNECT(surf_route_vivaldi);
-  XBT_LOG_CONNECT(surf_storage);
-  XBT_LOG_CONNECT(surf_trace);
-  XBT_LOG_CONNECT(surf_vm);
-  XBT_LOG_CONNECT(surf_host);
-
-#endif /* simgrid_EXPORTS */
-}
-
 static void xbt_log_help(void);
 static void xbt_log_help_categories(void);
 
@@ -264,24 +109,19 @@ static void xbt_log_help_categories(void);
 void xbt_log_init(int *argc, char **argv)
 {
   unsigned help_requested = 0;  /* 1: logs; 2: categories */
-  int i, j;
-  char *opt;
-
-  //    _XBT_LOGV(log).threshold = xbt_log_priority_debug; /* uncomment to set the LOG category to debug directly */
-
-  xbt_log_connect_categories();
+  int j                   = 1;
 
   /* Set logs and init log submodule */
-  for (j = i = 1; i < *argc; i++) {
+  for (int i = 1; i < *argc; i++) {
     if (!strncmp(argv[i], "--log=", strlen("--log="))) {
-      opt = strchr(argv[i], '=');
+      char* opt = strchr(argv[i], '=');
       opt++;
       xbt_log_control_set(opt);
       XBT_DEBUG("Did apply '%s' as log setting", opt);
     } else if (!strcmp(argv[i], "--help-logs")) {
-      help_requested |= 1;
+      help_requested |= 1U;
     } else if (!strcmp(argv[i], "--help-log-categories")) {
-      help_requested |= 2;
+      help_requested |= 2U;
     } else {
       argv[j++] = argv[i];
     }
@@ -327,7 +167,7 @@ void xbt_log_postexit(void)
   log_cat_exit(&_XBT_LOGV(XBT_LOG_ROOT_CAT));
 }
 
- /* Size of the static string in which we  build the log string */
+/* Size of the static string in which we build the log string */
 #define XBT_LOG_STATIC_BUFFER_SIZE 2048
 /* Minimum size of the dynamic string in which we build the log string
    (should be greater than XBT_LOG_STATIC_BUFFER_SIZE) */
@@ -341,65 +181,67 @@ void _xbt_log_event_log(xbt_log_event_t ev, const char *fmt, ...)
   xbt_assert(ev->priority < sizeof(xbt_log_priority_names), "Priority %d is greater than the biggest allowed value",
              ev->priority);
 
-  do {
+  while (1) {
     xbt_log_appender_t appender = cat->appender;
 
-    if (!appender)
-      continue;                 /* No appender, try next */
+    if (appender != NULL) {
+      xbt_assert(cat->layout, "No valid layout for the appender of category %s", cat->name);
 
-    xbt_assert(cat->layout, "No valid layout for the appender of category %s", cat->name);
-
-    /* First, try with a static buffer */
-    if (XBT_LOG_STATIC_BUFFER_SIZE) {
+      /* First, try with a static buffer */
+      int done = 0;
       char buff[XBT_LOG_STATIC_BUFFER_SIZE];
-      int done;
-      ev->buffer = buff;
+      ev->buffer      = buff;
       ev->buffer_size = sizeof buff;
       va_start(ev->ap, fmt);
       done = cat->layout->do_layout(cat->layout, ev, fmt);
       va_end(ev->ap);
       if (done) {
         appender->do_append(appender, buff);
-        continue;               /* Ok, that worked: go next */
+      } else {
+
+        /* The static buffer was too small, use a dynamically expanded one */
+        ev->buffer_size = XBT_LOG_DYNAMIC_BUFFER_SIZE;
+        ev->buffer      = xbt_malloc(ev->buffer_size);
+        while (1) {
+          va_start(ev->ap, fmt);
+          done = cat->layout->do_layout(cat->layout, ev, fmt);
+          va_end(ev->ap);
+          if (done)
+            break; /* Got it */
+          ev->buffer_size *= 2;
+          ev->buffer = xbt_realloc(ev->buffer, ev->buffer_size);
+        }
+        appender->do_append(appender, ev->buffer);
+        xbt_free(ev->buffer);
       }
     }
 
-    /* The static buffer was too small, use a dynamically expanded one */
-    ev->buffer_size = XBT_LOG_DYNAMIC_BUFFER_SIZE;
-    ev->buffer = xbt_malloc(ev->buffer_size);
-    while (1) {
-      int done;
-      va_start(ev->ap, fmt);
-      done = cat->layout->do_layout(cat->layout, ev, fmt);
-      va_end(ev->ap);
-      if (done)
-        break;                  /* Got it */
-      ev->buffer_size *= 2;
-      ev->buffer = xbt_realloc(ev->buffer, ev->buffer_size);
-    }
-    appender->do_append(appender, ev->buffer);
-    xbt_free(ev->buffer);
-
-  } while (cat->additivity && (cat = cat->parent, 1));
+    if (!cat->additivity)
+      break;
+    cat = cat->parent;
+  }
 }
 
-#undef XBT_LOG_DYNAMIC_BUFFER_SIZE
-#undef XBT_LOG_STATIC_BUFFER_SIZE
-
 /* NOTE:
  *
  * The standard logging macros use _XBT_LOG_ISENABLED, which calls _xbt_log_cat_init().  Thus, if we want to avoid an
  * infinite recursion, we can not use the standard logging macros in _xbt_log_cat_init(), and in all functions called
  * from it.
  *
- * To circumvent the problem, we define the macro_xbt_log_init() as (0) for the length of the affected functions, and
- * we do not forget to undefine it at the end!
+ * To circumvent the problem, we define the macro DISABLE_XBT_LOG_CAT_INIT() to hide the real _xbt_log_cat_init(). The
+ * macro has to be called at the beginning of the affected functions.
  */
+static int fake_xbt_log_cat_init(xbt_log_category_t XBT_ATTRIB_UNUSED category,
+                                 e_xbt_log_priority_t XBT_ATTRIB_UNUSED priority)
+{
+  return 0;
+}
+#define DISABLE_XBT_LOG_CAT_INIT()                                                                                     \
+  int (*_xbt_log_cat_init)(xbt_log_category_t, e_xbt_log_priority_t) XBT_ATTRIB_UNUSED = fake_xbt_log_cat_init;
 
 static void _xbt_log_cat_apply_set(xbt_log_category_t category, xbt_log_setting_t setting)
 {
-#define _xbt_log_cat_init(a, b) (0)
-
+  DISABLE_XBT_LOG_CAT_INIT();
   if (setting->thresh != xbt_log_priority_uninitialized) {
     xbt_log_threshold_set(category, setting->thresh);
 
@@ -426,7 +268,6 @@ static void _xbt_log_cat_apply_set(xbt_log_category_t category, xbt_log_setting_
     category->additivity = 0;
     XBT_DEBUG("Set %p as appender of category '%s'", setting->appender, category->name);
   }
-#undef _xbt_log_cat_init
 }
 
 /*
@@ -435,8 +276,7 @@ static void _xbt_log_cat_apply_set(xbt_log_category_t category, xbt_log_setting_
  */
 int _xbt_log_cat_init(xbt_log_category_t category, e_xbt_log_priority_t priority)
 {
-#define _xbt_log_cat_init(a, b) (0)
-
+  DISABLE_XBT_LOG_CAT_INIT();
   if (log_cat_init_mutex != NULL)
     xbt_os_mutex_acquire(log_cat_init_mutex);
 
@@ -448,7 +288,6 @@ int _xbt_log_cat_init(xbt_log_category_t category, e_xbt_log_priority_t priority
 
   unsigned int cursor;
   xbt_log_setting_t setting = NULL;
-  int found = 0;
 
   XBT_DEBUG("Initializing category '%s' (firstChild=%s, nextSibling=%s)", category->name,
          (category->firstChild ? category->firstChild->name : "none"),
@@ -468,7 +307,8 @@ int _xbt_log_cat_init(xbt_log_category_t category, e_xbt_log_priority_t priority
     xbt_log_parent_set(category, category->parent);
 
     if (XBT_LOG_ISENABLED(log, xbt_log_priority_debug)) {
-      char *buf, *res = NULL;
+      char *buf;
+      char *res = NULL;
       xbt_log_category_t cpp = category->parent->firstChild;
       while (cpp) {
         if (res) {
@@ -492,6 +332,7 @@ int _xbt_log_cat_init(xbt_log_category_t category, e_xbt_log_priority_t priority
   if (xbt_log_settings) {
     xbt_assert(category, "NULL category");
     xbt_assert(category->name);
+    int found = 0;
 
     xbt_dynar_foreach(xbt_log_settings, cursor, setting) {
       xbt_assert(setting, "Damnit, NULL cat in the list");
@@ -513,8 +354,6 @@ int _xbt_log_cat_init(xbt_log_category_t category, e_xbt_log_priority_t priority
   if (log_cat_init_mutex != NULL)
     xbt_os_mutex_release(log_cat_init_mutex);
   return priority >= category->threshold;
-
-#undef _xbt_log_cat_init
 }
 
 void xbt_log_parent_set(xbt_log_category_t cat, xbt_log_category_t parent)
@@ -574,7 +413,6 @@ static xbt_log_setting_t _xbt_log_parse_setting(const char *control_string)
 {
   const char *orig_control_string = control_string;
   xbt_log_setting_t set = xbt_new(s_xbt_log_setting_t, 1);
-  const char *name, *dot, *eq;
 
   set->catname = NULL;
   set->thresh = xbt_log_priority_uninitialized;
@@ -587,14 +425,13 @@ static xbt_log_setting_t _xbt_log_parse_setting(const char *control_string)
   XBT_DEBUG("Parse log setting '%s'", control_string);
 
   control_string += strspn(control_string, " ");
-  name = control_string;
-  control_string += strcspn(control_string, ".= ");
-  dot = control_string;
+  const char *name = control_string;
+  control_string += strcspn(control_string, ".:= ");
+  const char *dot = control_string;
   control_string += strcspn(control_string, ":= ");
-  eq = control_string;
+  const char *eq = control_string;
 
-  if(*dot != '.' && (*eq == '=' || *eq == ':'))
-    xbt_die ("Invalid control string '%s'", orig_control_string);
+  xbt_assert(*dot == '.' || (*eq != '=' && *eq != ':'), "Invalid control string '%s'", orig_control_string);
 
   if (!strncmp(dot + 1, "threshold", (size_t) (eq - dot - 1))) {
     int i;
@@ -652,9 +489,9 @@ static xbt_log_setting_t _xbt_log_parse_setting(const char *control_string)
     if (!strncmp(neweq, "file:", 5)) {
       set->appender = xbt_log_appender_file_new(neweq + 5);
     }else if (!strncmp(neweq, "rollfile:", 9)) {
-    set->appender = xbt_log_appender2_file_new(neweq + 9,1);
+      set->appender = xbt_log_appender2_file_new(neweq + 9,1);
     }else if (!strncmp(neweq, "splitfile:", 10)) {
-    set->appender = xbt_log_appender2_file_new(neweq + 10,0);
+      set->appender = xbt_log_appender2_file_new(neweq + 10,0);
     } else {
       THROWF(arg_error, 0, "Unknown appender log type: '%s'", neweq);
     }
@@ -664,7 +501,7 @@ static xbt_log_setting_t _xbt_log_parse_setting(const char *control_string)
   } else {
     char buff[512];
     snprintf(buff, MIN(512, eq - dot), "%s", dot + 1);
-    THROWF(arg_error, 0, "Unknown setting of the log category: '%s'", buff);
+    xbt_die("Unknown setting of the log category: '%s'", buff);
   }
   set->catname = (char *) xbt_malloc(dot - name + 1);
 
@@ -677,7 +514,8 @@ static xbt_log_setting_t _xbt_log_parse_setting(const char *control_string)
 
 static xbt_log_category_t _xbt_log_cat_searchsub(xbt_log_category_t cat, char *name)
 {
-  xbt_log_category_t child, res;
+  xbt_log_category_t child;
+  xbt_log_category_t res;
 
   XBT_DEBUG("Search '%s' into '%s' (firstChild='%s'; nextSibling='%s')", name,
          cat->name, (cat->firstChild ? cat->firstChild->name : "none"),
@@ -746,10 +584,8 @@ void xbt_log_control_set(const char *control_string)
 
   /* Parse each entry and either use it right now (if the category was already created), or store it for further use */
   xbt_dynar_foreach(set_strings, cpt, str) {
-    xbt_log_category_t cat = NULL;
-
     set = _xbt_log_parse_setting(str);
-    cat = _xbt_log_cat_searchsub(&_XBT_LOGV(XBT_LOG_ROOT_CAT), set->catname);
+    xbt_log_category_t cat = _xbt_log_cat_searchsub(&_XBT_LOGV(XBT_LOG_ROOT_CAT), set->catname);
 
     if (cat) {
       XBT_DEBUG("Apply directly");
@@ -776,7 +612,7 @@ void xbt_log_appender_set(xbt_log_category_t cat, xbt_log_appender_t app)
 
 void xbt_log_layout_set(xbt_log_category_t cat, xbt_log_layout_t lay)
 {
-#define _xbt_log_cat_init(a, b) (0)
+  DISABLE_XBT_LOG_CAT_INIT();
   if (!cat->appender) {
     XBT_VERB ("No appender to category %s. Setting the file appender as default", cat->name);
     xbt_log_appender_set(cat, xbt_log_appender_file_new(NULL));
@@ -789,7 +625,6 @@ void xbt_log_layout_set(xbt_log_category_t cat, xbt_log_layout_t lay)
   }
   cat->layout = lay;
   xbt_log_additivity_set(cat, 0);
-#undef _xbt_log_cat_init
 }
 
 void xbt_log_additivity_set(xbt_log_category_t cat, int additivity)
@@ -799,54 +634,57 @@ void xbt_log_additivity_set(xbt_log_category_t cat, int additivity)
 
 static void xbt_log_help(void)
 {
-  printf(
-"Description of the logging output:\n"
-"\n"
-"   Threshold configuration: --log=CATEGORY_NAME.thres:PRIORITY_LEVEL\n"
-"      CATEGORY_NAME: defined in code with function 'XBT_LOG_NEW_CATEGORY'\n"
-"      PRIORITY_LEVEL: the level to print (trace,debug,verbose,info,warning,error,critical)\n"
-"         -> trace: enter and return of some functions\n"
-"         -> debug: crufty output\n"
-"         -> verbose: verbose output for the user wanting more\n"
-"         -> info: output about the regular functionning\n"
-"         -> warning: minor issue encountered\n"
-"         -> error: issue encountered\n"
-"         -> critical: major issue encountered\n"
-"\n"
-"   Format configuration: --log=CATEGORY_NAME.fmt:OPTIONS\n"
-"      OPTIONS may be:\n"
-"         -> %%%%: the %% char\n"
-"         -> %%n: platform-dependent line separator (LOG4J compatible)\n"
-"         -> %%e: plain old space (SimGrid extension)\n"
-"\n"
-"         -> %%m: user-provided message\n"
-"\n"
-"         -> %%c: Category name (LOG4J compatible)\n"
-"         -> %%p: Priority name (LOG4J compatible)\n"
-"\n"
-"         -> %%h: Hostname (SimGrid extension)\n"
-"         -> %%P: Process name (SimGrid extension)\n"
-"         -> %%t: Thread \"name\" (LOG4J compatible -- actually the address of the thread in memory)\n"
-"         -> %%i: Process PID (SimGrid extension -- this is a 'i' as in 'i'dea)\n"
-"\n"
-"         -> %%F: file name where the log event was raised (LOG4J compatible)\n"
-"         -> %%l: location where the log event was raised (LOG4J compatible, like '%%F:%%L' -- this is a l as in 'l'etter)\n"
-"         -> %%L: line number where the log event was raised (LOG4J compatible)\n"
-"         -> %%M: function name (LOG4J compatible -- called method name here of course).\n"
-"                 Defined only when using gcc because there is no __FUNCTION__ elsewhere.\n"
-"\n"
-"         -> %%b: full backtrace (Called %%throwable in LOG4J). Defined only under windows or when using the GNU libc because\n"
-"                 backtrace() is not defined elsewhere, and we only have a fallback for windows boxes, not mac ones for example.\n"
-"         -> %%B: short backtrace (only the first line of the %%b). Called %%throwable{short} in LOG4J; defined where %%b is.\n"
-"\n"
-"         -> %%d: date (UNIX-like epoch)\n"
-"         -> %%r: application age (time elapsed since the beginning of the application)\n"
-"\n"
-"   Miscellaneous:\n"
-"      --help-log-categories    Display the current hierarchy of log categories.\n"
-"      --log=no_loc             Don't print file names in messages (for tesh tests).\n"
-"\n"
-    );
+  printf("Description of the logging output:\n"
+         "\n"
+         "   Threshold configuration: --log=CATEGORY_NAME.thres:PRIORITY_LEVEL\n"
+         "      CATEGORY_NAME: defined in code with function 'XBT_LOG_NEW_CATEGORY'\n"
+         "      PRIORITY_LEVEL: the level to print (trace,debug,verbose,info,warning,error,critical)\n"
+         "         -> trace: enter and return of some functions\n"
+         "         -> debug: crufty output\n"
+         "         -> verbose: verbose output for the user wanting more\n"
+         "         -> info: output about the regular functioning\n"
+         "         -> warning: minor issue encountered\n"
+         "         -> error: issue encountered\n"
+         "         -> critical: major issue encountered\n"
+         "      The default priority level is 'info'.\n"
+         "\n"
+         "   Format configuration: --log=CATEGORY_NAME.fmt:FORMAT\n"
+         "      FORMAT string may contain:\n"
+         "         -> %%%%: the %% char\n"
+         "         -> %%n: platform-dependent line separator (LOG4J compatible)\n"
+         "         -> %%e: plain old space (SimGrid extension)\n"
+         "\n"
+         "         -> %%m: user-provided message\n"
+         "\n"
+         "         -> %%c: Category name (LOG4J compatible)\n"
+         "         -> %%p: Priority name (LOG4J compatible)\n"
+         "\n"
+         "         -> %%h: Hostname (SimGrid extension)\n"
+         "         -> %%P: Process name (SimGrid extension)\n"
+         "         -> %%t: Thread \"name\" (LOG4J compatible -- actually the address of the thread in memory)\n"
+         "         -> %%i: Process PID (SimGrid extension -- this is a 'i' as in 'i'dea)\n"
+         "\n"
+         "         -> %%F: file name where the log event was raised (LOG4J compatible)\n"
+         "         -> %%l: location where the log event was raised (LOG4J compatible, like '%%F:%%L' -- this is a l as "
+         "in 'l'etter)\n"
+         "         -> %%L: line number where the log event was raised (LOG4J compatible)\n"
+         "         -> %%M: function name (LOG4J compatible -- called method name here of course).\n"
+         "                 Defined only when using gcc because there is no __func__ elsewhere.\n"
+         "\n"
+         "         -> %%b: full backtrace (Called %%throwable in LOG4J). Defined only under windows or when using the "
+         "GNU libc because\n"
+         "                 backtrace() is not defined elsewhere, and we only have a fallback for windows boxes, not "
+         "mac ones for example.\n"
+         "         -> %%B: short backtrace (only the first line of the %%b). Called %%throwable{short} in LOG4J; "
+         "defined where %%b is.\n"
+         "\n"
+         "         -> %%d: date (UNIX-like epoch)\n"
+         "         -> %%r: application age (time elapsed since the beginning of the application)\n"
+         "\n"
+         "   Miscellaneous:\n"
+         "      --help-log-categories    Display the current hierarchy of log categories.\n"
+         "      --log=no_loc             Don't print file names in messages (for tesh tests).\n"
+         "\n");
 }
 
 static int xbt_log_cat_cmp(const void *pa, const void *pb)
@@ -860,7 +698,6 @@ static void xbt_log_help_categories_rec(xbt_log_category_t category, const char
 {
   char *this_prefix;
   char *child_prefix;
-  xbt_dynar_t dynar;
   unsigned i;
   xbt_log_category_t cat;
 
@@ -875,16 +712,15 @@ static void xbt_log_help_categories_rec(xbt_log_category_t category, const char
     child_prefix = xbt_strdup(prefix);
   }
 
-  dynar = xbt_dynar_new(sizeof(xbt_log_category_t), NULL);
+  xbt_dynar_t dynar = xbt_dynar_new(sizeof(xbt_log_category_t), NULL);
   for (cat = category ; cat != NULL; cat = cat->nextSibling)
     xbt_dynar_push_as(dynar, xbt_log_category_t, cat);
 
   xbt_dynar_sort(dynar, xbt_log_cat_cmp);
 
-  for (i = 0; i < xbt_dynar_length(dynar); i++) {
+  xbt_dynar_foreach(dynar, i, cat){
     if (i == xbt_dynar_length(dynar) - 1 && category->parent)
       *strrchr(child_prefix, '|') = ' ';
-    cat = xbt_dynar_get_as(dynar, i, xbt_log_category_t);
     printf("%s%s: %s\n", this_prefix, cat->name, cat->description);
     xbt_log_help_categories_rec(cat->firstChild, child_prefix);
   }