Scippy

SCIP

Solving Constraint Integer Programs

message.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This1 file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2014 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file message.c
17  * @brief message output methods
18  * @author Tobias Achterberg
19  * @author Marc Pfetsch
20  * @author Michael Winkler
21  */
22 
23 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
24 
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <assert.h>
28 
29 #include "scip/type_message.h"
30 #include "scip/struct_message.h"
31 #include "scip/def.h"
32 #include "scip/pub_misc.h"
33 #include "blockmemshell/memory.h"
34 
35 
36 #ifndef va_copy
37 #define va_copy(dest, src) do { BMScopyMemory(&dest, &src); } while( 0 )
38 #endif
39 
40 /* do defines for windows directly her to make the lpi more independent*/
41 #if defined(_WIN32) || defined(_WIN64)
42 #define snprintf _snprintf
43 #define vsnprintf _vsnprintf
44 #endif
45 
46 /** handles the output of the given message */
47 static
49  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
50  SCIP_DECL_MESSAGEOUTPUTFUNC(outputfunc), /**< message handler function used for output */
51  FILE* file1, /**< file stream to print into, or NULL for stdout */
52  SCIP_Bool usefile1, /**< Should file1 be used? */
53  FILE* file2, /**< file stream to print into */
54  SCIP_Bool usefile2, /**< Should file2 be used? */
55  const char* msg, /**< message to print; NULL to flush the output buffer */
56  char* buffer, /**< message buffer */
57  int* bufferlen /**< pointer to the currently used entries in the message buffer */
58  )
59 {
60  const char* s;
61 
62  assert( messagehdlr != NULL );
63  assert( outputfunc != NULL );
64  assert( !usefile2 || file2 != NULL );
65  assert( buffer == NULL || bufferlen != NULL );
66 
67  /* if we do not have a buffer directly output the message */
68  if ( buffer == NULL )
69  {
70  /* we do not have a buffer, so it makes no sense to flush it if msg == NULL */
71  if ( msg != NULL )
72  {
73  if ( usefile1 )
74  outputfunc(messagehdlr, file1, msg);
75  if ( usefile2 )
76  outputfunc(messagehdlr, file2, msg);
77  }
78  return;
79  }
80  assert(bufferlen != NULL);
81 
82  /* should the buffer be flushed? */
83  if ( msg == NULL )
84  {
85  assert( *bufferlen < SCIP_MAXSTRLEN );
86  assert( buffer[*bufferlen] == '\0' );
87  if ( usefile1 )
88  outputfunc(messagehdlr, file1, buffer);
89  if ( usefile2 )
90  outputfunc(messagehdlr, file2, buffer);
91  *bufferlen = 0;
92  buffer[0] = '\0';
93  return;
94  }
95  assert( msg != NULL && buffer != NULL );
96 
97  /* if no output is activated, to not copy message into buffer */
98  if ( ! usefile1 && ! usefile2 )
99  return;
100 
101  /* determine message length and last newline (if any) */
102  s = msg;
103  while ( *s != '\0' )
104  {
105  /* if we reached a newline or the size limit, empty buffer and reset (need possibly space for newline and '\0') */
106  if ( *s == '\n' || *bufferlen >= SCIP_MAXSTRLEN-2 )
107  {
108  if ( *s == '\n' )
109  buffer[(*bufferlen)++] = *(s++);
110  buffer[*bufferlen] = '\0';
111 
112  if ( usefile1 )
113  outputfunc(messagehdlr, file1, buffer);
114  if ( usefile2 )
115  outputfunc(messagehdlr, file2, buffer);
116  *bufferlen = 0;
117  buffer[0] = '\0';
118  }
119  else
120  buffer[(*bufferlen)++] = *(s++);
121  }
122  buffer[*bufferlen] = '\0';
123 
124  return;
125 }
126 
127 /** default error printing method which is used to print all occurring errors */
128 static
129 SCIP_DECL_ERRORPRINTING(errorPrintingDefault)
130 { /*lint --e{715}*/
131  if ( msg != NULL )
132  fputs(msg, stderr);
133  fflush(stderr);
134 }
135 
136 /** static variable which holds the error printing method */
137 static SCIP_DECL_ERRORPRINTING((*staticErrorPrinting)) = errorPrintingDefault;
138 
139 /** static variable which holds a data pointer for the error prinint callback */
141 
142 /** prints error message with the current message handler, or buffers the message if no newline exists */
143 static
145  const char* msg /**< message to print; NULL to flush the output buffer */
146  )
147 {
148  if( staticErrorPrinting != NULL )
149  staticErrorPrinting(msg, staticErrorPrintingData);
150 }
151 
152 /** prints warning message with the current message handler, or buffers the message if no newline exists */
153 static
155  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
156  const char* msg /**< message to print; NULL to flush the output buffer */
157  )
158 { /*lint --e{715}*/
159  if ( messagehdlr != NULL && messagehdlr->messagewarning != NULL && (! messagehdlr->quiet || messagehdlr->logfile != NULL) )
160  {
161  handleMessage(messagehdlr, messagehdlr->messagewarning, stderr, ! messagehdlr->quiet, messagehdlr->logfile, (messagehdlr->logfile != NULL),
162  msg, messagehdlr->warningbuffer, &messagehdlr->warningbufferlen);
163  }
164 }
165 
166 /** prints dialog message with the current message handler, or buffers the message if no newline exists */
167 static
169  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
170  FILE* file, /**< file stream to print into, or NULL for stdout */
171  const char* msg /**< message to print; NULL to flush the output buffer */
172  )
173 { /*lint --e{715}*/
174  if ( messagehdlr != NULL && messagehdlr->messagedialog != NULL )
175  {
176  if ( (file == NULL || file == stdout) && ! messagehdlr->quiet )
177  {
178  handleMessage(messagehdlr, messagehdlr->messagedialog, (file == NULL) ? stdout : file, TRUE, messagehdlr->logfile, (messagehdlr->logfile != NULL),
179  msg, messagehdlr->dialogbuffer, &messagehdlr->dialogbufferlen);
180  }
181  else if ( msg != NULL )
182  {
183  /* file output cannot be buffered because the output file may change */
184  if ( *msg != '\0' )
185  {
186  handleMessage(messagehdlr, messagehdlr->messagedialog, file, ! messagehdlr->quiet, messagehdlr->logfile, (messagehdlr->logfile != NULL), msg, NULL, NULL);
187  }
188  }
189  }
190 }
191 
192 /** prints info message with the current message handler, or buffers the message if no newline exists */
193 static
195  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
196  FILE* file, /**< file stream to print into, or NULL for stdout */
197  const char* msg /**< message to print; NULL to flush the output buffer */
198  )
199 { /*lint --e{715}*/
200  if ( messagehdlr != NULL && messagehdlr->messageinfo != NULL )
201  {
202  if ( (file == NULL || file == stdout) && ! messagehdlr->quiet )
203  {
204  handleMessage(messagehdlr, messagehdlr->messageinfo, (file == NULL) ? stdout : file, TRUE, messagehdlr->logfile, (messagehdlr->logfile != NULL),
205  msg, messagehdlr->infobuffer, &messagehdlr->infobufferlen);
206  }
207  else if ( msg != NULL )
208  {
209  /* file output cannot be buffered because the output file may change or the message is to long */
210  if ( *msg != '\0' )
211  {
212  handleMessage(messagehdlr, messagehdlr->messagedialog, file, ! messagehdlr->quiet, messagehdlr->logfile, (messagehdlr->logfile != NULL), msg, NULL, NULL);
213  }
214  }
215  }
216 }
217 
218 /** if the given file is not NULL a log file is opened */
219 static
221  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
222  const char* filename /**< name of log file, or NULL (stdout) */
223  )
224 {
225  if( filename != NULL )
226  {
227  messagehdlr->logfile = fopen(filename, "a"); /* append to log file */
228 
229  if( messagehdlr->logfile == NULL )
230  {
231  SCIPerrorMessage("cannot open log file <%s> for writing\n", filename);
232  }
233  }
234  else
235  messagehdlr->logfile = NULL;
236 }
237 
238 /** frees message handler */
239 static
241  SCIP_MESSAGEHDLR** messagehdlr /**< pointer to the message handler */
242  )
243 {
244  assert(messagehdlr != NULL);
245 
246  if( *messagehdlr != NULL )
247  {
248  /* flush message buffers */
249  messagePrintWarning(*messagehdlr, NULL);
250  messagePrintDialog(*messagehdlr, NULL, NULL);
251  messagePrintInfo(*messagehdlr, NULL, NULL);
252 
253  if( (*messagehdlr)->messagehdlrfree != NULL )
254  {
255  /* call destructor method of message handler to free the message handler data */
256  SCIP_CALL( (*messagehdlr)->messagehdlrfree(*messagehdlr) );
257  }
258 
259  /* close the log file if one exists */
260  if( (*messagehdlr)->logfile != NULL )
261  {
262  fclose((*messagehdlr)->logfile);
263  }
264 
265  /* free buffer arrays */
266  BMSfreeMemoryArrayNull(&(*messagehdlr)->warningbuffer);
267  BMSfreeMemoryArrayNull(&(*messagehdlr)->dialogbuffer);
268  BMSfreeMemoryArrayNull(&(*messagehdlr)->infobuffer);
269  BMSfreeMemory(messagehdlr);
270  }
271 
272  return SCIP_OKAY;
273 }
274 
275 /** Creates and captures a message handler which deals with warning, information, and dialog (interactive shell) methods.
276  *
277  * @note The message handler does not handle error messages; see SCIPmessageSetErrorPrinting()
278  */
280  SCIP_MESSAGEHDLR** messagehdlr, /**< pointer to store the message handler */
281  SCIP_Bool bufferedoutput, /**< should the output be buffered up to the next newline? */
282  const char* filename, /**< name of log file, or NULL for no log */
283  SCIP_Bool quiet, /**< should screen messages be suppressed? */
284  SCIP_DECL_MESSAGEWARNING((*messagewarning)),/**< warning message print method of message handler */
285  SCIP_DECL_MESSAGEDIALOG((*messagedialog)),/**< dialog message print method of message handler */
286  SCIP_DECL_MESSAGEINFO ((*messageinfo)), /**< info message print method of message handler */
287  SCIP_DECL_MESSAGEHDLRFREE((*messagehdlrfree)), /**< destructor of message handler to free message handler data */
288  SCIP_MESSAGEHDLRDATA* messagehdlrdata /**< message handler data */
289  )
290 {
291  SCIP_ALLOC( BMSallocMemory(messagehdlr) );
292  (*messagehdlr)->messagewarning = messagewarning;
293  (*messagehdlr)->messagedialog = messagedialog;
294  (*messagehdlr)->messageinfo = messageinfo;
295  (*messagehdlr)->messagehdlrfree = messagehdlrfree;
296  (*messagehdlr)->messagehdlrdata = messagehdlrdata;
297  (*messagehdlr)->warningbuffer = NULL;
298  (*messagehdlr)->dialogbuffer = NULL;
299  (*messagehdlr)->infobuffer = NULL;
300  (*messagehdlr)->warningbufferlen = 0;
301  (*messagehdlr)->dialogbufferlen = 0;
302  (*messagehdlr)->infobufferlen = 0;
303  (*messagehdlr)->nuses = 1;
304 
305  (*messagehdlr)->quiet = quiet;
306  messagehdlrOpenLogfile(*messagehdlr, filename);
307 
308  /* allocate buffer for buffered output */
309  if( bufferedoutput )
310  {
311  SCIP_ALLOC( BMSallocMemoryArray(&(*messagehdlr)->warningbuffer, SCIP_MAXSTRLEN) ); /*lint !e506*/
312  SCIP_ALLOC( BMSallocMemoryArray(&(*messagehdlr)->dialogbuffer, SCIP_MAXSTRLEN) ); /*lint !e506*/
313  SCIP_ALLOC( BMSallocMemoryArray(&(*messagehdlr)->infobuffer, SCIP_MAXSTRLEN) ); /*lint !e506*/
314  (*messagehdlr)->warningbuffer[0] = '\0';
315  (*messagehdlr)->dialogbuffer[0] = '\0';
316  (*messagehdlr)->infobuffer[0] = '\0';
317  }
318 
319  return SCIP_OKAY;
320 }
321 
322 /** captures message handler */
324  SCIP_MESSAGEHDLR* messagehdlr /**< message handler, or NULL */
325  )
326 {
327  if( messagehdlr != NULL )
328  ++messagehdlr->nuses;
329 }
330 
331 /** releases message handler */
333  SCIP_MESSAGEHDLR** messagehdlr /**< pointer to the message handler */
334  )
335 {
336  assert(messagehdlr != NULL);
337 
338  if( *messagehdlr == NULL )
339  return SCIP_OKAY;
340 
341  assert((*messagehdlr)->nuses >= 1);
342 
343  /* decrement usage counter */
344  --(*messagehdlr)->nuses;
345 
346  /* the last one turns the light off */
347  if( (*messagehdlr)->nuses == 0 )
348  {
349  SCIP_CALL( messagehdlrFree(messagehdlr) );
350  assert(*messagehdlr == NULL);
351  }
352  else
353  {
354  *messagehdlr = NULL;
355  }
356 
357  return SCIP_OKAY;
358 }
359 
360 /** sets the user data of the message handler */
362  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler; must not be NULL */
363  SCIP_MESSAGEHDLRDATA* messagehdlrdata /**< new message handler data to attach to the handler */
364  )
365 {
366  assert(messagehdlr != NULL);
367 
368  if( messagehdlr == NULL ) /*lint !e774*/
369  return SCIP_INVALIDDATA;
370 
371  messagehdlr->messagehdlrdata = messagehdlrdata;
372 
373  return SCIP_OKAY;
374 }
375 
376 /** sets the log file name for the message handler */
378  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
379  const char* filename /**< log file name where to copy messages into, or NULL */
380  )
381 {
382  assert(messagehdlr != NULL);
383 
384  /* close the old log file if one exists */
385  if( messagehdlr->logfile != NULL )
386  {
387  fclose(messagehdlr->logfile);
388  }
389 
390  /* opens the log file */
391  messagehdlrOpenLogfile(messagehdlr, filename);
392 }
393 
394 /** sets the messages handler to be quiet */
396  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
397  SCIP_Bool quiet /**< should screen messages be suppressed? */
398  )
399 {
400  assert(messagehdlr != NULL);
401 
402  /* flush message buffers in order to not loose information */
403  messagePrintWarning(messagehdlr, NULL);
404  messagePrintDialog(messagehdlr, NULL, NULL);
405  messagePrintInfo(messagehdlr, NULL, NULL);
406 
407  messagehdlr->quiet = quiet;
408 }
409 
410 /** prints a warning message, acting like the printf() command */
412  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
413  const char* formatstr, /**< format string like in printf() function */
414  ... /**< format arguments line in printf() function */
415  )
416 {
417  va_list ap;
418 
419  va_start(ap, formatstr); /*lint !e826*/
420  SCIPmessageVFPrintWarning(messagehdlr, formatstr, ap);
421  va_end(ap);
422 }
423 
424 /** prints a warning message, acting like the vprintf() command */
426  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
427  const char* formatstr, /**< format string like in printf() function */
428  va_list ap /**< variable argument list */
429  )
430 {
431  SCIPmessageVFPrintWarning(messagehdlr, formatstr, ap);
432 }
433 
434 /** prints a warning message, acting like the fprintf() command */
436  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
437  const char* formatstr, /**< format string like in printf() function */
438  ... /**< format arguments line in printf() function */
439  )
440 {
441  va_list ap;
442 
443  va_start(ap, formatstr); /*lint !e826*/
444  SCIPmessageVFPrintWarning(messagehdlr, formatstr, ap);
445  va_end(ap);
446 }
447 
448 /** prints a warning message, acting like the vfprintf() command */
450  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
451  const char* formatstr, /**< format string like in printf() function */
452  va_list ap /**< variable argument list */
453  )
454 {
455  char msg[SCIP_MAXSTRLEN];
456  int n;
457  va_list aq;
458 
459  va_copy(aq, ap);
460 
461  n = vsnprintf(msg, SCIP_MAXSTRLEN, formatstr, ap);
462  if( n < 0 )
463  msg[SCIP_MAXSTRLEN-1] = '\0';
464  else if( n >= SCIP_MAXSTRLEN )
465  {
466  char* bigmsg;
467 #ifndef NDEBUG
468  int m;
469 #endif
470 
471  if( BMSallocMemorySize(&bigmsg, n+1) == NULL )
472  {
473  va_end(aq);
474  return;
475  }
476 
477 #ifndef NDEBUG
478  m = vsnprintf(bigmsg, (size_t) n+1, formatstr, aq);
479 #else
480  vsnprintf(bigmsg, (size_t) n+1, formatstr, aq);
481 #endif
482  assert(m == n);
483  va_end(aq);
484  messagePrintWarning(messagehdlr, bigmsg);
485  BMSfreeMemory(&bigmsg);
486  return;
487  }
488 
489  messagePrintWarning(messagehdlr, msg);
490  va_end(aq);
491 }
492 
493 /** prints a dialog message that requests user interaction, acting like the printf() command */
495  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
496  const char* formatstr, /**< format string like in printf() function */
497  ... /**< format arguments line in printf() function */
498  )
499 {
500  va_list ap;
501 
502  va_start(ap, formatstr); /*lint !e826*/
503  SCIPmessageVFPrintDialog(messagehdlr, NULL, formatstr, ap);
504  va_end(ap);
505 }
506 
507 /** prints a dialog message that requests user interaction, acting like the vprintf() command */
509  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
510  const char* formatstr, /**< format string like in printf() function */
511  va_list ap /**< variable argument list */
512  )
513 {
514  SCIPmessageVFPrintDialog(messagehdlr, NULL, formatstr, ap);
515 }
516 
517 /** prints a dialog message that requests user interaction into a file, acting like the fprintf() command */
519  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
520  FILE* file, /**< file stream to print into, or NULL for stdout */
521  const char* formatstr, /**< format string like in printf() function */
522  ... /**< format arguments line in printf() function */
523  )
524 {
525  va_list ap;
526 
527  va_start(ap, formatstr); /*lint !e826*/
528  SCIPmessageVFPrintDialog(messagehdlr, file, formatstr, ap);
529  va_end(ap);
530 }
531 
532 /** prints a dialog message that requests user interaction into a file, acting like the vfprintf() command */
534  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
535  FILE* file, /**< file stream to print into, or NULL for stdout */
536  const char* formatstr, /**< format string like in printf() function */
537  va_list ap /**< variable argument list */
538  )
539 {
540  char msg[SCIP_MAXSTRLEN];
541  int n;
542  va_list aq;
543 
544  va_copy(aq, ap);
545 
546  n = vsnprintf(msg, SCIP_MAXSTRLEN, formatstr, ap);
547  if( n < 0 )
548  msg[SCIP_MAXSTRLEN-1] = '\0';
549  else if( n >= SCIP_MAXSTRLEN )
550  {
551  char* bigmsg;
552 #ifndef NDEBUG
553  int m;
554 #endif
555 
556  if( BMSallocMemorySize(&bigmsg, n+1) == NULL )
557  {
558  va_end(aq);
559  return;
560  }
561 
562 #ifndef NDEBUG
563  m = vsnprintf(bigmsg, (size_t) n+1, formatstr, aq);
564 #else
565  vsnprintf(bigmsg, (size_t) n+1, formatstr, aq);
566 #endif
567  assert(m == n);
568  va_end(aq);
569  messagePrintDialog(messagehdlr, file, bigmsg);
570  BMSfreeMemory(&bigmsg);
571  return;
572  }
573  messagePrintDialog(messagehdlr, file, msg);
574  va_end(aq);
575 }
576 
577 /** prints a message, acting like the printf() command */
579  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
580  const char* formatstr, /**< format string like in printf() function */
581  ... /**< format arguments line in printf() function */
582  )
583 {
584  va_list ap;
585 
586  va_start(ap, formatstr); /*lint !e826*/
587  SCIPmessageVFPrintInfo(messagehdlr, NULL, formatstr, ap);
588  va_end(ap);
589 }
590 
591 /** prints a message, acting like the vprintf() command */
593  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
594  const char* formatstr, /**< format string like in printf() function */
595  va_list ap /**< variable argument list */
596  )
597 {
598  SCIPmessageVFPrintInfo(messagehdlr, NULL, formatstr, ap);
599 }
600 
601 /** prints a message into a file, acting like the fprintf() command */
603  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
604  FILE* file, /**< file stream to print into, or NULL for stdout */
605  const char* formatstr, /**< format string like in printf() function */
606  ... /**< format arguments line in printf() function */
607  )
608 {
609  va_list ap;
610 
611  va_start(ap, formatstr); /*lint !e826*/
612  SCIPmessageVFPrintInfo(messagehdlr, file, formatstr, ap);
613  va_end(ap);
614 }
615 
616 /** prints a message into a file, acting like the vfprintf() command */
618  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
619  FILE* file, /**< file stream to print into, or NULL for stdout */
620  const char* formatstr, /**< format string like in printf() function */
621  va_list ap /**< variable argument list */
622  )
623 {
624  char msg[SCIP_MAXSTRLEN];
625  int n;
626  va_list aq;
627 
628  va_copy(aq, ap);
629 
630  n = vsnprintf(msg, SCIP_MAXSTRLEN, formatstr, ap);
631  if( n < 0 )
632  msg[SCIP_MAXSTRLEN-1] = '\0';
633  else if( n >= SCIP_MAXSTRLEN )
634  {
635  char* bigmsg;
636 #ifndef NDEBUG
637  int m;
638 #endif
639 
640  if( BMSallocMemorySize(&bigmsg, n+1) == NULL )
641  {
642  va_end(aq);
643  return;
644  }
645 
646 #ifndef NDEBUG
647  m = vsnprintf(bigmsg, (size_t) n+1, formatstr, aq);
648 #else
649  vsnprintf(bigmsg, (size_t) n+1, formatstr, aq);
650 #endif
651  assert(m == n);
652  va_end(aq);
653  messagePrintInfo(messagehdlr, file, bigmsg);
654  BMSfreeMemory(&bigmsg);
655  return;
656  }
657  messagePrintInfo(messagehdlr, file, msg);
658  va_end(aq);
659 }
660 
661 /** prints a message depending on the verbosity level, acting like the printf() command */
663  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
664  SCIP_VERBLEVEL verblevel, /**< current verbosity level */
665  SCIP_VERBLEVEL msgverblevel, /**< verbosity level of this message */
666  const char* formatstr, /**< format string like in printf() function */
667  ... /**< format arguments line in printf() function */
668  )
669 {
670  va_list ap;
671 
672  va_start(ap, formatstr); /*lint !e826*/
673  SCIPmessageVFPrintVerbInfo(messagehdlr, verblevel, msgverblevel, NULL, formatstr, ap);
674  va_end(ap);
675 }
676 
677 /** prints a message depending on the verbosity level, acting like the vprintf() command */
679  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
680  SCIP_VERBLEVEL verblevel, /**< current verbosity level */
681  SCIP_VERBLEVEL msgverblevel, /**< verbosity level of this message */
682  const char* formatstr, /**< format string like in printf() function */
683  va_list ap /**< variable argument list */
684  )
685 {
686  SCIPmessageVFPrintVerbInfo(messagehdlr, verblevel, msgverblevel, NULL, formatstr, ap);
687 }
688 
689 /** prints a message into a file depending on the verbosity level, acting like the fprintf() command */
691  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
692  SCIP_VERBLEVEL verblevel, /**< current verbosity level */
693  SCIP_VERBLEVEL msgverblevel, /**< verbosity level of this message */
694  FILE* file, /**< file stream to print into, or NULL for stdout */
695  const char* formatstr, /**< format string like in printf() function */
696  ... /**< format arguments line in printf() function */
697  )
698 {
699  va_list ap;
700 
701  va_start(ap, formatstr); /*lint !e826*/
702  SCIPmessageVFPrintVerbInfo(messagehdlr, verblevel, msgverblevel, file, formatstr, ap);
703  va_end(ap);
704 }
705 
706 /** prints a message into a file depending on the verbosity level, acting like the vfprintf() command */
708  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
709  SCIP_VERBLEVEL verblevel, /**< current verbosity level */
710  SCIP_VERBLEVEL msgverblevel, /**< verbosity level of this message */
711  FILE* file, /**< file stream to print into, or NULL for stdout */
712  const char* formatstr, /**< format string like in printf() function */
713  va_list ap /**< variable argument list */
714  )
715 {
716  assert(msgverblevel > SCIP_VERBLEVEL_NONE);
717  assert(msgverblevel <= SCIP_VERBLEVEL_FULL);
718  assert(verblevel <= SCIP_VERBLEVEL_FULL);
719 
720  if( msgverblevel <= verblevel )
721  {
722  char msg[SCIP_MAXSTRLEN];
723  int n;
724  va_list aq;
725 
726  va_copy(aq, ap);
727 
728  n = vsnprintf(msg, SCIP_MAXSTRLEN, formatstr, ap);
729  if( n < 0 )
730  msg[SCIP_MAXSTRLEN-1] = '\0';
731  else if( n >= SCIP_MAXSTRLEN )
732  {
733  char* bigmsg;
734 #ifndef NDEBUG
735  int m;
736 #endif
737 
738  if( BMSallocMemorySize(&bigmsg, n+1) == NULL )
739  {
740  va_end(aq);
741  return;
742  }
743 
744 #ifndef NDEBUG
745  m = vsnprintf(bigmsg, (size_t) n+1, formatstr, aq);
746 #else
747  vsnprintf(bigmsg, (size_t) n+1, formatstr, aq);
748 #endif
749  assert(m == n);
750  va_end(aq);
751  messagePrintInfo(messagehdlr, file, bigmsg);
752  BMSfreeMemory(&bigmsg);
753  return;
754  }
755  messagePrintInfo(messagehdlr, file, msg);
756  va_end(aq);
757  }
758 }
759 
760 /** prints the header with source file location for an error message using the static message handler */
762  const char* sourcefile, /**< name of the source file that called the function */
763  int sourceline /**< line in the source file where the function was called */
764  )
765 {
766  char msg[SCIP_MAXSTRLEN];
767 
768  /* safe string printing - do not use SCIPsnprintf() since message.c should be independent */
769  (void) snprintf(msg, SCIP_MAXSTRLEN, "[%s:%d] ERROR: ", sourcefile, sourceline);
770  msg[SCIP_MAXSTRLEN-1] = '\0';
771  messagePrintError(msg);
772 }
773 
774 /** prints a error message, acting like the printf() command */
776  const char* formatstr, /**< format string like in printf() function */
777  ... /**< format arguments line in printf() function */
778  )
779 {
780  va_list ap;
781 
782  va_start(ap, formatstr); /*lint !e826*/
783  SCIPmessageVPrintError(formatstr, ap);
784  va_end(ap);
785 }
786 
787 /** prints an error message, acting like the vprintf() command using the static message handler */
789  const char* formatstr, /**< format string like in printf() function */
790  va_list ap /**< variable argument list */
791  )
792 {
793  char msg[SCIP_MAXSTRLEN];
794  int n;
795  va_list aq;
796 
797  va_copy(aq, ap);
798 
799  n = vsnprintf(msg, SCIP_MAXSTRLEN, formatstr, ap);
800  if( n < 0 )
801  msg[SCIP_MAXSTRLEN-1] = '\0';
802  else if( n >= SCIP_MAXSTRLEN )
803  {
804  char* bigmsg;
805 #ifndef NDEBUG
806  int m;
807 #endif
808 
809  if( BMSallocMemorySize(&bigmsg, n+1) == NULL )
810  {
811  va_end(aq);
812  return;
813  }
814 
815 #ifndef NDEBUG
816  m = vsnprintf(bigmsg, (size_t) n+1, formatstr, aq);
817 #else
818  vsnprintf(bigmsg, (size_t) n+1, formatstr, aq);
819 #endif
820  assert(m == n);
821  va_end(aq);
822  messagePrintError(bigmsg);
823  BMSfreeMemory(&bigmsg);
824  return;
825  }
826 
827  messagePrintError(msg);
828  va_end(aq);
829 }
830 
831 /** Method to set the error printing method. Setting the error printing method to NULL will suspend all error methods.
832  *
833  * @note The error printing method is static variable. That means all occurring errors are handled via that methods
834  */
836  SCIP_DECL_ERRORPRINTING((*errorPrinting)),/**< error message print method of message handler, or NULL */
837  void* data /**< data pointer which will be passed to the error printing method, or NULL */
838  )
839 {
840  staticErrorPrinting = errorPrinting;
841  staticErrorPrintingData = data;
842 }
843 
844 /** Method to set the error printing method to default version prints everything the stderr.
845  *
846  * @note The error printing method is a static variable. This means that all occurring errors are handled via this method.
847  */
849  void
850  )
851 {
852  staticErrorPrinting = errorPrintingDefault;
853  staticErrorPrintingData = NULL;
854 }
855 
856 /*
857  * simple functions implemented as defines
858  */
859 
860 /* In debug mode, the following methods are implemented as function calls to ensure
861  * type validity.
862  * In optimized mode, the methods are implemented as defines to improve performance.
863  * However, we want to have them in the library anyways, so we have to undef the defines.
864  */
865 
866 #undef SCIPmessagehdlrGetData
867 #undef SCIPmessagehdlrGetLogfile
868 #undef SCIPmessagehdlrIsQuiet
869 
870 /** returns the user data of the message handler */
872  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
873  )
874 {
875  if( messagehdlr != NULL )
876  return messagehdlr->messagehdlrdata;
877  else
878  return NULL;
879 }
880 
881 
882 /** returns the log file or NULL for stdout */
884  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
885  )
886 {
887  if( messagehdlr == NULL )
888  return NULL;
889 
890  return messagehdlr->logfile;
891 }
892 
893 /** returns TRUE if the message handler is set to be quiet */
895  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
896  )
897 {
898  return (messagehdlr == NULL || messagehdlr->quiet);
899 }
900