ROOT  6.05/03
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
gmessages.c
Go to the documentation of this file.
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 
20 /*
21  * Modified by the GLib Team and others 1997-2000. See the AUTHORS
22  * file for a list of people on the GLib Team. See the ChangeLog
23  * files for a list of changes. These files are distributed with
24  * GLib at ftp://ftp.gtk.org/pub/gtk/.
25  */
26 
27 /*
28  * MT safe
29  */
30 
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34 
35 #include <stdlib.h>
36 #include <stdarg.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include "glib.h"
40 #ifdef HAVE_UNISTD_H
41 #include <unistd.h>
42 #endif
43 #include <signal.h>
44 #include <locale.h>
45 #include <errno.h>
46 
47 #ifdef G_OS_WIN32
48 typedef FILE* GFileDescriptor;
49 #else
51 #endif
52 
53 /* --- structures --- */
54 typedef struct _GLogDomain GLogDomain;
55 typedef struct _GLogHandler GLogHandler;
56 struct _GLogDomain
57 {
58  gchar *log_domain;
59  GLogLevelFlags fatal_mask;
60  GLogHandler *handlers;
62 };
63 struct _GLogHandler
64 {
65  guint id;
66  GLogLevelFlags log_level;
67  GLogFunc log_func;
68  gpointer data;
70 };
71 
72 
73 /* --- prototypes --- */
75  gboolean may_warn,
76  va_list args);
77 
78 
79 /* --- variables --- */
80 
82 
83 const gchar *g_log_domain_glib = "GLib";
88 
90 
91 /* --- functions --- */
92 #ifdef G_OS_WIN32
93 # define STRICT
94 # include <windows.h>
95 # undef STRICT
96 # include <process.h> /* For _getpid() */
97 
98 static gboolean alloc_console_called = FALSE;
99 
100 static gboolean gonna_abort = FALSE;
101 
102 /* This default message will usually be overwritten. */
103 /* Yes, a fixed size buffer is bad. So sue me. But g_error is never
104  * with huge strings, is it? */
105 static char fatal_msg_buf[1000] = "Unspecified fatal error encountered, aborting.";
106 static char *fatal_msg_ptr = fatal_msg_buf;
107 
108 /* Just use stdio. If we're out of memory, we're hosed anyway. */
109 #undef write
110 static inline int
111 dowrite (GFileDescriptor fd,
112  const void *buf,
113  unsigned int len)
114 {
115  if (gonna_abort)
116  {
117  memcpy (fatal_msg_ptr, buf, len);
118  fatal_msg_ptr += len;
119  *fatal_msg_ptr = 0;
120  return len;
121  }
122 
123  fwrite (buf, len, 1, fd);
124  fflush (fd);
125 
126  return len;
127 }
128 
129 #define write(fd, buf, len) dowrite(fd, buf, len)
130 
131 static void
132 ensure_stdout_valid (void)
133 {
134  HANDLE handle;
135 
136  if (gonna_abort)
137  return;
138 
139  if (!alloc_console_called)
140  {
141  handle = GetStdHandle (STD_OUTPUT_HANDLE);
142 
143  if (handle == INVALID_HANDLE_VALUE)
144  {
145  AllocConsole ();
146  alloc_console_called = TRUE;
147  freopen ("CONOUT$", "w", stdout);
148  }
149  }
150 }
151 #else
152 #define ensure_stdout_valid() /* Define as empty */
153 #endif
154 
155 static void
156 write_unsigned (GFileDescriptor fd,
157  gulong num,
158  guint radix)
159 {
160  char buffer[64];
161  gulong tmp;
162  char c;
163  int i, n;
164 
165  g_return_if_fail (radix >= 2 && radix <= 36);
166 
167  if (!num)
168  {
169  write (fd, "0", 1);
170  return;
171  }
172 
173  if (radix == 16)
174  write (fd, "0x", 2);
175  else if (radix == 8)
176  write (fd, "0", 1);
177 
178  n = 0;
179  tmp = num;
180  while (tmp)
181  {
182  tmp /= radix;
183  n++;
184  }
185 
186  i = n;
187  while (num)
188  {
189  i--;
190  c = (num % radix);
191  if (c < 10)
192  buffer[i] = c + '0';
193  else
194  buffer[i] = c + 'a' - 10;
195  num /= radix;
196  }
197 
198  write (fd, buffer, n);
199 }
200 
201 static void
202 write_string (GFileDescriptor fd,
203  gchar *string)
204 {
205  write (fd, string, strlen (string));
206 }
207 
208 static void
209 g_log_write_prefix (GFileDescriptor fd,
210  GLogLevelFlags mask)
211 {
213  static gboolean initialized = FALSE;
214 
215  g_mutex_lock (g_messages_lock);
216 
217  if (!initialized)
218  {
219  const gchar *val;
220  initialized = TRUE;
221 
222  val = g_getenv ("G_MESSAGES_PREFIXED");
223 
224  if (val)
225  {
226  static const GDebugKey keys[] = {
227  { "error", G_LOG_LEVEL_ERROR },
228  { "critical", G_LOG_LEVEL_CRITICAL },
229  { "warning", G_LOG_LEVEL_WARNING },
230  { "message", G_LOG_LEVEL_MESSAGE },
231  { "info", G_LOG_LEVEL_INFO },
232  { "debug", G_LOG_LEVEL_DEBUG }
233  };
234 
235  g_log_msg_prefix = g_parse_debug_string (val, keys, G_N_ELEMENTS (keys));
236  }
237  }
238 
239  g_mutex_unlock (g_messages_lock);
240 
241  if ((g_log_msg_prefix & mask) == mask)
242  {
243  gchar *prg_name;
244 
245  prg_name = g_get_prgname ();
246 
247  if (!prg_name)
248  write_string (fd, "(process:");
249  else
250  {
251  write_string (fd, prg_name);
252  write_string (fd, " (pid:");
253  }
254 
255  write_unsigned (fd, getpid (), 10);
256  write_string (fd, "): ");
257  }
258 }
259 
260 static inline GLogDomain*
261 g_log_find_domain (const gchar *log_domain)
262 {
263  register GLogDomain *domain;
264 
265  g_mutex_lock (g_messages_lock);
266  domain = g_log_domains;
267  while (domain)
268  {
269  if (strcmp (domain->log_domain, log_domain) == 0)
270  {
271  g_mutex_unlock (g_messages_lock);
272  return domain;
273  }
274  domain = domain->next;
275  }
276  g_mutex_unlock (g_messages_lock);
277  return NULL;
278 }
279 
280 static inline GLogDomain*
281 g_log_domain_new (const gchar *log_domain)
282 {
283  register GLogDomain *domain;
284 
285  domain = g_new (GLogDomain, 1);
286  domain->log_domain = g_strdup (log_domain);
287  domain->fatal_mask = G_LOG_FATAL_MASK;
288  domain->handlers = NULL;
289 
290  g_mutex_lock (g_messages_lock);
291  domain->next = g_log_domains;
292  g_log_domains = domain;
293  g_mutex_unlock (g_messages_lock);
294 
295  return domain;
296 }
297 
298 static inline void
300 {
301  if (domain->fatal_mask == G_LOG_FATAL_MASK &&
302  domain->handlers == NULL)
303  {
304  register GLogDomain *last, *work;
305 
306  last = NULL;
307 
308  g_mutex_lock (g_messages_lock);
309  work = g_log_domains;
310  while (work)
311  {
312  if (work == domain)
313  {
314  if (last)
315  last->next = domain->next;
316  else
317  g_log_domains = domain->next;
318  g_free (domain->log_domain);
319  g_free (domain);
320  break;
321  }
322  last = work;
323  work = last->next;
324  }
325  g_mutex_unlock (g_messages_lock);
326  }
327 }
328 
329 static inline GLogFunc
331  GLogLevelFlags log_level,
332  gpointer *data)
333 {
334  if (domain && log_level)
335  {
336  register GLogHandler *handler;
337 
338  handler = domain->handlers;
339  while (handler)
340  {
341  if ((handler->log_level & log_level) == log_level)
342  {
343  *data = handler->data;
344  return handler->log_func;
345  }
346  handler = handler->next;
347  }
348  }
349  return g_log_default_handler;
350 }
351 
354 {
355  GLogLevelFlags old_mask;
356 
357  /* restrict the global mask to levels that are known to glib */
358  fatal_mask &= (1 << G_LOG_LEVEL_USER_SHIFT) - 1;
359  /* force errors to be fatal */
360  fatal_mask |= G_LOG_LEVEL_ERROR;
361  /* remove bogus flag */
362  fatal_mask &= ~G_LOG_FLAG_FATAL;
363 
364  g_mutex_lock (g_messages_lock);
365  old_mask = g_log_always_fatal;
366  g_log_always_fatal = fatal_mask;
367  g_mutex_unlock (g_messages_lock);
368 
369  return old_mask;
370 }
371 
373 g_log_set_fatal_mask (const gchar *log_domain,
374  GLogLevelFlags fatal_mask)
375 {
376  GLogLevelFlags old_flags;
377  register GLogDomain *domain;
378 
379  if (!log_domain)
380  log_domain = "";
381 
382  /* force errors to be fatal */
383  fatal_mask |= G_LOG_LEVEL_ERROR;
384  /* remove bogus flag */
385  fatal_mask &= ~G_LOG_FLAG_FATAL;
386 
387  domain = g_log_find_domain (log_domain);
388  if (!domain)
389  domain = g_log_domain_new (log_domain);
390  old_flags = domain->fatal_mask;
391 
392  domain->fatal_mask = fatal_mask;
393  g_log_domain_check_free (domain);
394 
395  return old_flags;
396 }
397 
398 guint
399 g_log_set_handler (const gchar *log_domain,
400  GLogLevelFlags log_levels,
401  GLogFunc log_func,
402  gpointer user_data)
403 {
404  register GLogDomain *domain;
405  register GLogHandler *handler;
406  static guint handler_id = 0;
407 
408  g_return_val_if_fail ((log_levels & G_LOG_LEVEL_MASK) != 0, 0);
409  g_return_val_if_fail (log_func != NULL, 0);
410 
411  if (!log_domain)
412  log_domain = "";
413 
414  domain = g_log_find_domain (log_domain);
415  if (!domain)
416  domain = g_log_domain_new (log_domain);
417 
418  handler = g_new (GLogHandler, 1);
419  g_mutex_lock (g_messages_lock);
420  handler->id = ++handler_id;
421  g_mutex_unlock (g_messages_lock);
422  handler->log_level = log_levels;
423  handler->log_func = log_func;
424  handler->data = user_data;
425  handler->next = domain->handlers;
426  domain->handlers = handler;
427 
428  return handler_id;
429 }
430 
431 void
432 g_log_remove_handler (const gchar *log_domain,
433  guint handler_id)
434 {
435  register GLogDomain *domain;
436 
437  g_return_if_fail (handler_id > 0);
438 
439  if (!log_domain)
440  log_domain = "";
441 
442  domain = g_log_find_domain (log_domain);
443  if (domain)
444  {
445  register GLogHandler *work, *last;
446 
447  last = NULL;
448  work = domain->handlers;
449  while (work)
450  {
451  if (work->id == handler_id)
452  {
453  if (last)
454  last->next = work->next;
455  else
456  domain->handlers = work->next;
457  g_free (work);
458  g_log_domain_check_free (domain);
459  return;
460  }
461  last = work;
462  work = last->next;
463  }
464  }
465  g_warning ("g_log_remove_handler(): could not find handler with id `%d' for domain \"%s\"",
466  handler_id,
467  log_domain);
468 }
469 
470 void
471 g_logv (const gchar *log_domain,
472  GLogLevelFlags log_level,
473  const gchar *format,
474  va_list args1)
475 {
476  va_list args2;
477  gchar buffer[1025];
478  register gint i;
479 
480  log_level &= G_LOG_LEVEL_MASK;
481  if (!log_level)
482  return;
483 
484  /* we use a stack buffer of fixed size, because we might get called
485  * recursively.
486  */
487 #ifdef HAVE_VSNPRINTF
488  vsnprintf (buffer, 1024, format, args1);
489 #else /* !HAVE_VSNPRINTF */
490  G_VA_COPY (args2, args1);
491  if (printf_string_upper_bound (format, FALSE, args1) < 1024)
492  vsprintf (buffer, format, args2);
493  else
494  {
495  /* since we might be out of memory, we can't use g_vsnprintf(). */
496  /* we are out of luck here */
497  strncpy (buffer, format, 1024);
498  buffer[1024] = 0;
499  }
500  va_end (args2);
501 #endif /* !HAVE_VSNPRINTF */
502 
503  for (i = g_bit_nth_msf (log_level, -1); i >= 0; i = g_bit_nth_msf (log_level, i))
504  {
505  register GLogLevelFlags test_level;
506 
507  test_level = 1 << i;
508  if (log_level & test_level)
509  {
510  guint depth = GPOINTER_TO_UINT (g_private_get (g_log_depth));
511  GLogDomain *domain;
512  GLogFunc log_func;
513  gpointer data = NULL;
514 
515  domain = g_log_find_domain (log_domain ? log_domain : "");
516 
517  if (depth)
518  test_level |= G_LOG_FLAG_RECURSION;
519 
520  depth++;
521  g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
522 
523  g_mutex_lock (g_messages_lock);
524  if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) |
525  g_log_always_fatal) & test_level) != 0)
526  test_level |= G_LOG_FLAG_FATAL;
527  g_mutex_unlock (g_messages_lock);
528 
529  log_func = g_log_domain_get_handler (domain, test_level, &data);
530  log_func (log_domain, test_level, buffer, data);
531 
532  /* *domain can be cluttered now */
533 
534  if (test_level & G_LOG_FLAG_FATAL)
535  {
536 #if defined (G_ENABLE_DEBUG) && defined (SIGTRAP)
537  if (!(test_level & G_LOG_FLAG_RECURSION))
538  G_BREAKPOINT ();
539  else
540  abort ();
541 #else /* !G_ENABLE_DEBUG || !SIGTRAP */
542 #ifdef G_OS_WIN32
543  MessageBox (NULL, fatal_msg_buf, NULL, MB_OK);
544 #endif
545 # if defined (_MSC_VER) && defined (_DEBUG)
546  /* let's see the call stack ... */
547  __asm int 3
548 # endif
549  abort ();
550 #endif /* !G_ENABLE_DEBUG || !SIGTRAP */
551  }
552 
553  depth--;
554  g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
555  }
556  }
557 }
558 
559 void
560 g_log (const gchar *log_domain,
561  GLogLevelFlags log_level,
562  const gchar *format,
563  ...)
564 {
565  va_list args;
566 
567  va_start (args, format);
568  g_logv (log_domain, log_level, format, args);
569  va_end (args);
570 }
571 
572 void
573 g_log_default_handler (const gchar *log_domain,
574  GLogLevelFlags log_level,
575  const gchar *message,
576  gpointer unused_data)
577 {
578  GFileDescriptor fd;
579  gboolean in_recursion;
580  gboolean is_fatal;
581 
582  in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
583  is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
584  log_level &= G_LOG_LEVEL_MASK;
585 
586  if (!message)
587  message = "g_log_default_handler(): (NULL) message";
588 
589 #ifdef G_OS_WIN32
590  /* Use just stdout as stderr is hard to get redirected from the
591  * DOS prompt.
592  */
593  fd = stdout;
594  gonna_abort = is_fatal;
595 #else
596  fd = (log_level > G_LOG_LEVEL_MESSAGE) ? 1 : 2;
597 #endif
598 
599  switch (log_level)
600  {
601  case G_LOG_LEVEL_ERROR:
602  /* use write(2) for output, in case we are out of memeory */
604  write (fd, "\n", 1);
605  g_log_write_prefix (fd, log_level);
606 
607  if (log_domain)
608  {
609  write (fd, log_domain, strlen (log_domain));
610  write (fd, "-", 1);
611  }
612  else
613  write (fd, "** ", 3);
614  if (in_recursion)
615  write (fd, "ERROR (recursed) **: ", 21);
616  else
617  write (fd, "ERROR **: ", 10);
618  write (fd, message, strlen (message));
619  if (is_fatal)
620  write (fd, "\naborting...\n", 13);
621  else
622  write (fd, "\n", 1);
623  break;
626  write (fd, "\n", 1);
627  g_log_write_prefix (fd, log_level);
628 
629  if (log_domain)
630  {
631  write (fd, log_domain, strlen (log_domain));
632  write (fd, "-", 1);
633  }
634  else
635  write (fd, "** ", 3);
636  if (in_recursion)
637  write (fd, "CRITICAL (recursed) **: ", 24);
638  else
639  write (fd, "CRITICAL **: ", 13);
640  write (fd, message, strlen (message));
641  if (is_fatal)
642  write (fd, "\naborting...\n", 13);
643  else
644  write (fd, "\n", 1);
645  break;
646  case G_LOG_LEVEL_WARNING:
648  write (fd, "\n", 1);
649  g_log_write_prefix (fd, log_level);
650 
651  if (log_domain)
652  {
653  write (fd, log_domain, strlen (log_domain));
654  write (fd, "-", 1);
655  }
656  else
657  write (fd, "** ", 3);
658  if (in_recursion)
659  write (fd, "WARNING (recursed) **: ", 23);
660  else
661  write (fd, "WARNING **: ", 12);
662  write (fd, message, strlen (message));
663  if (is_fatal)
664  write (fd, "\naborting...\n", 13);
665  else
666  write (fd, "\n", 1);
667  break;
668  case G_LOG_LEVEL_MESSAGE:
670 
671  g_log_write_prefix (fd, log_level);
672 
673  if (log_domain)
674  {
675  write (fd, log_domain, strlen (log_domain));
676  write (fd, "-", 1);
677  }
678  if (in_recursion)
679  write (fd, "Message (recursed): ", 20);
680  else
681  write (fd, "Message: ", 9);
682  write (fd, message, strlen (message));
683  if (is_fatal)
684  write (fd, "\naborting...\n", 13);
685  else
686  write (fd, "\n", 1);
687  break;
688  case G_LOG_LEVEL_INFO:
690 
691  g_log_write_prefix (fd, log_level);
692 
693  if (log_domain)
694  {
695  write (fd, log_domain, strlen (log_domain));
696  write (fd, "-", 1);
697  }
698  if (in_recursion)
699  write (fd, "INFO (recursed): ", 17);
700  else
701  write (fd, "INFO: ", 6);
702  write (fd, message, strlen (message));
703  if (is_fatal)
704  write (fd, "\naborting...\n", 13);
705  else
706  write (fd, "\n", 1);
707  break;
708  case G_LOG_LEVEL_DEBUG:
710 
711  g_log_write_prefix (fd, log_level);
712 
713  if (log_domain)
714  {
715  write (fd, log_domain, strlen (log_domain));
716  write (fd, "-", 1);
717  }
718  if (in_recursion)
719  write (fd, "DEBUG (recursed): ", 18);
720  else
721  write (fd, "DEBUG: ", 7);
722  write (fd, message, strlen (message));
723  if (is_fatal)
724  write (fd, "\naborting...\n", 13);
725  else
726  write (fd, "\n", 1);
727  break;
728  default:
729  /* we are used for a log level that is not defined by GLib itself,
730  * try to make the best out of it.
731  */
733 
734  g_log_write_prefix (fd, log_level);
735 
736  if (log_domain)
737  {
738  write (fd, log_domain, strlen (log_domain));
739  if (in_recursion)
740  write (fd, "-LOG (recursed:", 15);
741  else
742  write (fd, "-LOG (", 6);
743  }
744  else if (in_recursion)
745  write (fd, "LOG (recursed:", 14);
746  else
747  write (fd, "LOG (", 5);
748  if (log_level)
749  {
750  gchar string[] = "0x00): ";
751  gchar *p = string + 2;
752  guint i;
753 
754  i = g_bit_nth_msf (log_level, -1);
755  *p = i >> 4;
756  p++;
757  *p = '0' + (i & 0xf);
758  if (*p > '9')
759  *p += 'A' - '9' - 1;
760 
761  write (fd, string, 7);
762  }
763  else
764  write (fd, "): ", 3);
765  write (fd, message, strlen (message));
766  if (is_fatal)
767  write (fd, "\naborting...\n", 13);
768  else
769  write (fd, "\n", 1);
770  break;
771  }
772 }
773 
776 {
777  GPrintFunc old_print_func;
778 
779  g_mutex_lock (g_messages_lock);
780  old_print_func = glib_print_func;
781  glib_print_func = func;
782  g_mutex_unlock (g_messages_lock);
783 
784  return old_print_func;
785 }
786 
787 void
789  ...)
790 {
791  va_list args;
792  gchar *string;
793  GPrintFunc local_glib_print_func;
794 
795  g_return_if_fail (format != NULL);
796 
797  va_start (args, format);
798  string = g_strdup_vprintf (format, args);
799  va_end (args);
800 
801  g_mutex_lock (g_messages_lock);
802  local_glib_print_func = glib_print_func;
803  g_mutex_unlock (g_messages_lock);
804 
805  if (local_glib_print_func)
806  local_glib_print_func (string);
807  else
808  {
810  fputs (string, stdout);
811  fflush (stdout);
812  }
813  g_free (string);
814 }
815 
818 {
819  GPrintFunc old_printerr_func;
820 
821  g_mutex_lock (g_messages_lock);
822  old_printerr_func = glib_printerr_func;
823  glib_printerr_func = func;
824  g_mutex_unlock (g_messages_lock);
825 
826  return old_printerr_func;
827 }
828 
829 void
831  ...)
832 {
833  va_list args;
834  gchar *string;
835  GPrintFunc local_glib_printerr_func;
836 
837  g_return_if_fail (format != NULL);
838 
839  va_start (args, format);
840  string = g_strdup_vprintf (format, args);
841  va_end (args);
842 
843  g_mutex_lock (g_messages_lock);
844  local_glib_printerr_func = glib_printerr_func;
845  g_mutex_unlock (g_messages_lock);
846 
847  if (local_glib_printerr_func)
848  local_glib_printerr_func (string);
849  else
850  {
851  fputs (string, stderr);
852  fflush (stderr);
853  }
854  g_free (string);
855 }
856 
857 #ifndef MB_LEN_MAX
858 # define MB_LEN_MAX 8
859 #endif
860 
861 typedef struct
862 {
863  guint min_width;
864  guint precision;
865  gboolean alternate_format, zero_padding, adjust_left, locale_grouping;
866  gboolean add_space, add_sign, possible_sign, seen_precision;
867  gboolean mod_half, mod_long, mod_extra_long;
868 } PrintfArgSpec;
869 
870 static gsize
872  gboolean may_warn,
873  va_list args)
874 {
875  static const gboolean honour_longs = sizeof(long) > 4 || sizeof(void*) > 4;
876  gsize len = 1;
877 
878  if (!format)
879  return len;
880 
881  while (*format)
882  {
883  register gchar c = *format++;
884 
885  if (c != '%')
886  len += 1;
887  else /* (c == '%') */
888  {
889  PrintfArgSpec spec = { 0, };
890  gboolean seen_l = FALSE, conv_done = FALSE;
891  gsize conv_len = 0;
892  const gchar *spec_start = format;
893 
894  do
895  {
896  c = *format++;
897  switch (c)
898  {
899  GDoubleIEEE754 u_double;
900  guint v_uint;
901  gint v_int;
902  const gchar *v_string;
903 
904  /* beware of positional parameters
905  */
906  case '$':
907  if (may_warn)
909  "(): unable to handle positional parameters (%%n$)");
910  len += 1024; /* try adding some safety padding */
911  conv_done = TRUE;
912  break;
913 
914  /* parse flags
915  */
916  case '#':
917  spec.alternate_format = TRUE;
918  break;
919  case '0':
920  spec.zero_padding = TRUE;
921  break;
922  case '-':
923  spec.adjust_left = TRUE;
924  break;
925  case ' ':
926  spec.add_space = TRUE;
927  break;
928  case '+':
929  spec.add_sign = TRUE;
930  break;
931  case '\'':
932  spec.locale_grouping = TRUE;
933  break;
934 
935  /* parse output size specifications
936  */
937  case '.':
938  spec.seen_precision = TRUE;
939  break;
940  case '1':
941  case '2':
942  case '3':
943  case '4':
944  case '5':
945  case '6':
946  case '7':
947  case '8':
948  case '9':
949  v_uint = c - '0';
950  c = *format;
951  while (c >= '0' && c <= '9')
952  {
953  format++;
954  v_uint = v_uint * 10 + c - '0';
955  c = *format;
956  }
957  if (spec.seen_precision)
958  spec.precision = MAX (spec.precision, v_uint);
959  else
960  spec.min_width = MAX (spec.min_width, v_uint);
961  break;
962  case '*':
963  v_int = va_arg (args, int);
964  if (spec.seen_precision)
965  {
966  /* forget about negative precision */
967  if (v_int >= 0)
968  spec.precision = MAX (spec.precision, v_int);
969  }
970  else
971  {
972  if (v_int < 0)
973  {
974  v_int = - v_int;
975  spec.adjust_left = TRUE;
976  }
977  spec.min_width = MAX (spec.min_width, v_int);
978  }
979  break;
980 
981  /* parse type modifiers
982  */
983  case 'h':
984  spec.mod_half = TRUE;
985  break;
986  case 'l':
987  if (!seen_l)
988  {
989  spec.mod_long = TRUE;
990  seen_l = TRUE;
991  break;
992  }
993  /* else, fall through */
994  case 'L':
995  case 'q':
996  spec.mod_long = TRUE;
997  spec.mod_extra_long = TRUE;
998  break;
999  case 'z':
1000  case 'Z':
1001 #if GLIB_SIZEOF_SIZE_T > 4
1002  spec.mod_long = TRUE;
1003  spec.mod_extra_long = TRUE;
1004 #endif /* GLIB_SIZEOF_SIZE_T > 4 */
1005  break;
1006  case 't':
1007 #if GLIB_SIZEOF_PTRDIFF_T > 4
1008  spec.mod_long = TRUE;
1009  spec.mod_extra_long = TRUE;
1010 #endif /* GLIB_SIZEOF_PTRDIFF_T > 4 */
1011  break;
1012  case 'j':
1013 #if GLIB_SIZEOF_INTMAX_T > 4
1014  spec.mod_long = TRUE;
1015  spec.mod_extra_long = TRUE;
1016 #endif /* GLIB_SIZEOF_INTMAX_T > 4 */
1017  break;
1018 
1019  /* parse output conversions
1020  */
1021  case '%':
1022  conv_len += 1;
1023  break;
1024  case 'O':
1025  case 'D':
1026  case 'I':
1027  case 'U':
1028  /* some C libraries feature long variants for these as well? */
1029  spec.mod_long = TRUE;
1030  /* fall through */
1031  case 'o':
1032  conv_len += 2;
1033  /* fall through */
1034  case 'd':
1035  case 'i':
1036  conv_len += 1; /* sign */
1037  /* fall through */
1038  case 'u':
1039  conv_len += 4;
1040  /* fall through */
1041  case 'x':
1042  case 'X':
1043  spec.possible_sign = TRUE;
1044  conv_len += 10;
1045  if (spec.mod_long && honour_longs)
1046  conv_len *= 2;
1047  if (spec.mod_extra_long)
1048  conv_len *= 2;
1049  if (spec.mod_extra_long)
1050  {
1051 #ifdef G_HAVE_GINT64
1052  (void) va_arg (args, gint64);
1053 #else /* !G_HAVE_GINT64 */
1054  (void) va_arg (args, long);
1055 #endif /* !G_HAVE_GINT64 */
1056  }
1057  else if (spec.mod_long)
1058  (void) va_arg (args, long);
1059  else
1060  (void) va_arg (args, int);
1061  break;
1062  case 'A':
1063  case 'a':
1064  /* 0x */
1065  conv_len += 2;
1066  /* fall through */
1067  case 'g':
1068  case 'G':
1069  case 'e':
1070  case 'E':
1071  case 'f':
1072  spec.possible_sign = TRUE;
1073  /* n . dddddddddddddddddddddddd E +- eeee */
1074  conv_len += 1 + 1 + MAX (24, spec.precision) + 1 + 1 + 4;
1075  if (may_warn && spec.mod_extra_long)
1077  "(): unable to handle long double, collecting double only");
1078 #ifdef HAVE_LONG_DOUBLE
1079 #error need to implement special handling for long double
1080 #endif
1081  u_double.v_double = va_arg (args, double);
1082  /* %f can expand up to all significant digits before '.' (308) */
1083  if (c == 'f' &&
1084  u_double.mpn.biased_exponent > 0 && u_double.mpn.biased_exponent < 2047)
1085  {
1086  gint exp = u_double.mpn.biased_exponent;
1087 
1088  exp -= G_IEEE754_DOUBLE_BIAS;
1089  exp = exp * G_LOG_2_BASE_10 + 1;
1090  conv_len += ABS (exp); /* exp can be <0 */
1091  }
1092  /* some printf() implementations require extra padding for rounding */
1093  conv_len += 2;
1094  /* we can't really handle locale specific grouping here */
1095  if (spec.locale_grouping)
1096  conv_len *= 2;
1097  break;
1098  case 'C':
1099  spec.mod_long = TRUE;
1100  /* fall through */
1101  case 'c':
1102  conv_len += spec.mod_long ? MB_LEN_MAX : 1;
1103  (void) va_arg (args, int);
1104  break;
1105  case 'S':
1106  spec.mod_long = TRUE;
1107  /* fall through */
1108  case 's':
1109  v_string = va_arg (args, char*);
1110  if (!v_string)
1111  conv_len += 8; /* hold "(null)" */
1112  else if (spec.seen_precision)
1113  conv_len += spec.precision;
1114  else
1115  conv_len += strlen (v_string);
1116  conv_done = TRUE;
1117  if (spec.mod_long)
1118  {
1119  if (may_warn)
1121  "(): unable to handle wide char strings");
1122  len += 1024; /* try adding some safety padding */
1123  }
1124  break;
1125  case 'P': /* do we actually need this? */
1126  /* fall through */
1127  case 'p':
1128  spec.alternate_format = TRUE;
1129  conv_len += 10;
1130  if (honour_longs)
1131  conv_len *= 2;
1132  /* fall through */
1133  case 'n':
1134  conv_done = TRUE;
1135  (void) va_arg (args, void*);
1136  break;
1137  case 'm':
1138  /* there's not much we can do to be clever */
1139  v_string = g_strerror (errno);
1140  v_uint = v_string ? strlen (v_string) : 0;
1141  conv_len += MAX (256, v_uint);
1142  break;
1143 
1144  /* handle invalid cases
1145  */
1146  case '\000':
1147  /* no conversion specification, bad bad */
1148  conv_len += format - spec_start;
1149  break;
1150  default:
1151  if (may_warn)
1153  "(): unable to handle `%c' while parsing format",
1154  c);
1155  break;
1156  }
1157  conv_done |= conv_len > 0;
1158  }
1159  while (!conv_done);
1160  /* handle width specifications */
1161  conv_len = MAX (conv_len, MAX (spec.precision, spec.min_width));
1162  /* handle flags */
1163  conv_len += spec.alternate_format ? 2 : 0;
1164  conv_len += (spec.add_space || spec.add_sign || spec.possible_sign);
1165  /* finally done */
1166  len += conv_len;
1167  } /* else (c == '%') */
1168  } /* while (*format) */
1169 
1170  return len;
1171 }
1172 
1173 gsize
1175  va_list args)
1176 {
1177  return printf_string_upper_bound (format, TRUE, args);
1178 }
1179 
1180 void
1182 {
1183  g_messages_lock = g_mutex_new();
1184  g_log_depth = g_private_new(NULL);
1185 }
#define G_LOG_2_BASE_10
Definition: g_types.h:272
static GLogDomain * g_log_find_domain(const gchar *log_domain)
Definition: gmessages.c:261
unsigned int guint
Definition: g_types.h:51
guint biased_exponent
Definition: gtypes.h:288
gint GFileDescriptor
Definition: gmessages.c:50
double write(int n, const std::string &file_name, const std::string &vector_type, int compress=0)
writing
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
#define INVALID_HANDLE_VALUE
Definition: TMapFile.cxx:84
void g_messages_init(void)
Definition: gmessages.c:1181
#define g_return_val_if_fail(expr, val)
Definition: gmessages.h:300
#define G_VA_COPY(ap1, ap2)
Definition: gutils.h:65
static GPrintFunc glib_print_func
Definition: gmessages.c:86
#define ensure_stdout_valid()
Definition: gmessages.c:152
const gchar * g_log_domain_glib
Definition: gmessages.c:83
void(* GPrintFunc)(const gchar *string)
Definition: gmessages.h:165
gchar * g_strdup_vprintf(const gchar *format, va_list args1)
Definition: gstrfuncs.c:183
static std::string format(double x, double y, int digits, int width)
#define G_LOG_FATAL_MASK
Definition: gmessages.h:65
G_BEGIN_DECLS typedef char gchar
Definition: g_types.h:41
static GLogDomain * g_log_domains
Definition: gmessages.c:84
guint32 gsize
struct _GLogDomain GLogDomain
Definition: gmessages.c:54
static GMutex * g_messages_lock
Definition: gmessages.c:81
struct _GPrivate GPrivate
Definition: gthread.h:67
gint gboolean
Definition: g_types.h:45
#define g_mutex_new()
Definition: gthread.h:183
#define GPOINTER_TO_UINT(p)
static void write_string(GFileDescriptor fd, gchar *string)
Definition: gmessages.c:202
G_CONST_RETURN gchar * g_getenv(const gchar *variable)
Definition: gutils.c:671
#define G_LOG_LEVEL_USER_SHIFT
Definition: gmessages.h:43
XFontStruct * id
Definition: TGX11.cxx:104
static gsize printf_string_upper_bound(const gchar *format, gboolean may_warn, va_list args)
Definition: gmessages.c:871
struct _GDoubleIEEE754::@75 mpn
unsigned long gulong
Definition: g_types.h:50
#define g_mutex_unlock(mutex)
Definition: gthread.h:154
#define g_return_if_fail(expr)
Definition: gmessages.h:288
#define G_IEEE754_DOUBLE_BIAS
Definition: g_types.h:270
#define G_N_ELEMENTS(arr)
Definition: gmacros.h:149
gsize g_printf_string_upper_bound(const gchar *format, va_list args)
Definition: gmessages.c:1174
#define g_new(struct_type, n_structs)
Definition: gmem.h:60
int gint
Definition: g_types.h:44
static GLogFunc g_log_domain_get_handler(GLogDomain *domain, GLogLevelFlags log_level, gpointer *data)
Definition: gmessages.c:330
GLogLevelFlags g_log_set_fatal_mask(const gchar *log_domain, GLogLevelFlags fatal_mask)
Definition: gmessages.c:373
#define FALSE
Definition: gmacros.h:126
static GPrivate * g_log_depth
Definition: gmessages.c:89
G_CONST_RETURN gchar * g_strerror(gint errnum)
Definition: gstrfuncs.c:301
void * gpointer
Definition: g_types.h:67
GPrintFunc g_set_print_handler(GPrintFunc func)
Definition: gmessages.c:775
#define GUINT_TO_POINTER(u)
#define g_private_new(destructor)
Definition: gthread.h:188
GLogLevelFlags
Definition: gmessages.h:47
guint g_parse_debug_string(const gchar *string, const GDebugKey *keys, guint nkeys)
Definition: gutils.c:427
GPrintFunc g_set_printerr_handler(GPrintFunc func)
Definition: gmessages.c:817
#define g_mutex_lock(mutex)
Definition: gthread.h:150
#define G_GNUC_PRETTY_FUNCTION
Definition: gmacros.h:90
#define MAX(a, b)
Definition: gmacros.h:134
static GLogLevelFlags g_log_always_fatal
Definition: gmessages.c:85
#define ABS(a)
Definition: gmacros.h:140
GLogLevelFlags g_log_set_always_fatal(GLogLevelFlags fatal_mask)
Definition: gmessages.c:353
gchar data[7]
void g_free(gpointer mem)
Definition: gmem.c:183
void(* GLogFunc)(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
Definition: gmessages.h:67
guint g_log_set_handler(const gchar *log_domain, GLogLevelFlags log_levels, GLogFunc log_func, gpointer user_data)
Definition: gmessages.c:399
void g_printerr(const gchar *format,...)
Definition: gmessages.c:830
double func(double *x, double *p)
Definition: stressTF1.cxx:213
#define MB_LEN_MAX
Definition: gmessages.c:858
G_GNUC_EXTENSION typedef signed long long gint64
Definition: glibconfig.h:48
unsigned int len
Definition: cp1255.h:87
static void g_log_write_prefix(GFileDescriptor fd, GLogLevelFlags mask)
Definition: gmessages.c:209
typedef void((*Func_t)())
static void g_warning(const gchar *format,...)
Definition: gmessages.h:155
static GLogDomain * g_log_domain_new(const gchar *log_domain)
Definition: gmessages.c:281
G_INLINE_FUNC gint g_bit_nth_msf(gulong mask, gint nth_bit)
#define TRUE
Definition: gmacros.h:130
#define NULL
Definition: Rtypes.h:82
gchar * g_get_prgname(void)
Definition: gutils.c:1009
#define g_private_set(private_key, value)
Definition: gthread.h:192
struct _GLogHandler GLogHandler
Definition: gmessages.c:55
void g_log(const gchar *log_domain, GLogLevelFlags log_level, const gchar *format,...)
Definition: gmessages.c:560
#define g_private_get(private_key)
Definition: gthread.h:189
void g_print(const gchar *format,...)
Definition: gmessages.c:788
string message
Definition: ROOT.py:94
double exp(double)
void g_log_default_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer unused_data)
Definition: gmessages.c:573
gchar * g_strdup(const gchar *str)
Definition: gstrfuncs.c:82
struct _GMutex GMutex
Definition: gthread.h:65
const Int_t n
Definition: legend1.C:16
static void g_log_domain_check_free(GLogDomain *domain)
Definition: gmessages.c:299
static void write_unsigned(GFileDescriptor fd, gulong num, guint radix)
Definition: gmessages.c:156
void g_logv(const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, va_list args1)
Definition: gmessages.c:471
gdouble v_double
Definition: gtypes.h:284
void g_log_remove_handler(const gchar *log_domain, guint handler_id)
Definition: gmessages.c:432
static GPrintFunc glib_printerr_func
Definition: gmessages.c:87
#define G_BREAKPOINT()
Definition: gbacktrace.h:56