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-2018 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 visit 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/struct_message.h"
30 #include "scip/pub_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  {
133  if ( file != NULL )
134  fputs(msg, file);
135  else
136  fputs(msg, stderr);
137  }
138  fflush(stderr);
139 }
140 
141 /** static variable which holds the error printing method */
142 static SCIP_DECL_ERRORPRINTING((*staticErrorPrinting)) = errorPrintingDefault;
143 
144 /** static variable which holds a data pointer for the error prinint callback */
146 
147 /** prints error message with the current static message handler */
148 static
150  FILE* file, /**< file stream to print error, or NULL for stderr */
151  const char* msg /**< message to print; NULL to flush the output buffer */
152  )
153 {
154  if( staticErrorPrinting != NULL )
155  staticErrorPrinting(staticErrorPrintingData, file, msg);
156 }
157 
158 /** prints warning message with the current message handler, or buffers the message if no newline exists */
159 static
161  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
162  const char* msg /**< message to print; NULL to flush the output buffer */
163  )
164 { /*lint --e{715}*/
165  if ( messagehdlr != NULL && messagehdlr->messagewarning != NULL && (! messagehdlr->quiet || messagehdlr->logfile != NULL) )
166  {
167  handleMessage(messagehdlr, messagehdlr->messagewarning, stderr, ! messagehdlr->quiet, messagehdlr->logfile, (messagehdlr->logfile != NULL),
168  msg, messagehdlr->warningbuffer, &messagehdlr->warningbufferlen);
169  }
170 }
171 
172 /** prints dialog message with the current message handler, or buffers the message if no newline exists */
173 static
175  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
176  FILE* file, /**< file stream to print into, or NULL for stdout */
177  const char* msg /**< message to print; NULL to flush the output buffer */
178  )
179 { /*lint --e{715}*/
180  if ( messagehdlr != NULL && messagehdlr->messagedialog != NULL )
181  {
182  if ( (file == NULL || file == stdout) && ! messagehdlr->quiet )
183  {
184  handleMessage(messagehdlr, messagehdlr->messagedialog, (file == NULL) ? stdout : file, TRUE, messagehdlr->logfile, (messagehdlr->logfile != NULL),
185  msg, messagehdlr->dialogbuffer, &messagehdlr->dialogbufferlen);
186  }
187  else if ( msg != NULL )
188  {
189  /* file output cannot be buffered because the output file may change */
190  if ( *msg != '\0' )
191  {
192  handleMessage(messagehdlr, messagehdlr->messagedialog, file, !messagehdlr->quiet || (file != NULL && file != stdout), messagehdlr->logfile, (messagehdlr->logfile != NULL), msg, NULL, NULL);
193  }
194  }
195  }
196 }
197 
198 /** prints info message with the current message handler, or buffers the message if no newline exists */
199 static
201  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
202  FILE* file, /**< file stream to print into, or NULL for stdout */
203  const char* msg /**< message to print; NULL to flush the output buffer */
204  )
205 { /*lint --e{715}*/
206  if ( messagehdlr != NULL && messagehdlr->messageinfo != NULL )
207  {
208  if ( (file == NULL || file == stdout) && ! messagehdlr->quiet )
209  {
210  handleMessage(messagehdlr, messagehdlr->messageinfo, (file == NULL) ? stdout : file, TRUE, messagehdlr->logfile, (messagehdlr->logfile != NULL),
211  msg, messagehdlr->infobuffer, &messagehdlr->infobufferlen);
212  }
213  else if ( msg != NULL )
214  {
215  /* file output cannot be buffered because the output file may change or the message is to long */
216  if ( *msg != '\0' )
217  {
218  handleMessage(messagehdlr, messagehdlr->messagedialog, file, !messagehdlr->quiet || (file != NULL && file != stdout), messagehdlr->logfile, (messagehdlr->logfile != NULL), msg, NULL, NULL);
219  }
220  }
221  }
222 }
223 
224 /** if the given file is not NULL a log file is opened */
225 static
227  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
228  const char* filename /**< name of log file, or NULL (stdout) */
229  )
230 {
231  if( filename != NULL )
232  {
233  messagehdlr->logfile = fopen(filename, "a"); /* append to log file */
234 
235  if( messagehdlr->logfile == NULL )
236  {
237  SCIPerrorMessage("cannot open log file <%s> for writing\n", filename);
238  }
239  }
240  else
241  messagehdlr->logfile = NULL;
242 }
243 
244 /** frees message handler */
245 static
247  SCIP_MESSAGEHDLR** messagehdlr /**< pointer to the message handler */
248  )
249 {
250  assert(messagehdlr != NULL);
251 
252  if( *messagehdlr != NULL )
253  {
254  /* flush message buffers */
255  messagePrintWarning(*messagehdlr, NULL);
256  messagePrintDialog(*messagehdlr, NULL, NULL);
257  messagePrintInfo(*messagehdlr, NULL, NULL);
258 
259  if( (*messagehdlr)->messagehdlrfree != NULL )
260  {
261  /* call destructor method of message handler to free the message handler data */
262  SCIP_CALL( (*messagehdlr)->messagehdlrfree(*messagehdlr) );
263  }
264 
265  /* close the log file if one exists */
266  if( (*messagehdlr)->logfile != NULL )
267  {
268  fclose((*messagehdlr)->logfile);
269  }
270 
271  /* free buffer arrays */
272  BMSfreeMemoryArrayNull(&(*messagehdlr)->warningbuffer);
273  BMSfreeMemoryArrayNull(&(*messagehdlr)->dialogbuffer);
274  BMSfreeMemoryArrayNull(&(*messagehdlr)->infobuffer);
275  BMSfreeMemory(messagehdlr);
276  }
277 
278  return SCIP_OKAY;
279 }
280 
281 /** Creates and captures a message handler which deals with warning, information, and dialog (interactive shell) methods.
282  *
283  * @note The message handler does not handle error messages; see SCIPmessageSetErrorPrinting()
284  */
286  SCIP_MESSAGEHDLR** messagehdlr, /**< pointer to store the message handler */
287  SCIP_Bool bufferedoutput, /**< should the output be buffered up to the next newline? */
288  const char* filename, /**< name of log file, or NULL for no log */
289  SCIP_Bool quiet, /**< should screen messages be suppressed? */
290  SCIP_DECL_MESSAGEWARNING((*messagewarning)),/**< warning message print method of message handler */
291  SCIP_DECL_MESSAGEDIALOG((*messagedialog)),/**< dialog message print method of message handler */
292  SCIP_DECL_MESSAGEINFO ((*messageinfo)), /**< info message print method of message handler */
293  SCIP_DECL_MESSAGEHDLRFREE((*messagehdlrfree)), /**< destructor of message handler to free message handler data */
294  SCIP_MESSAGEHDLRDATA* messagehdlrdata /**< message handler data */
295  )
296 {
297  SCIP_ALLOC( BMSallocMemory(messagehdlr) );
298  (*messagehdlr)->messagewarning = messagewarning;
299  (*messagehdlr)->messagedialog = messagedialog;
300  (*messagehdlr)->messageinfo = messageinfo;
301  (*messagehdlr)->messagehdlrfree = messagehdlrfree;
302  (*messagehdlr)->messagehdlrdata = messagehdlrdata;
303  (*messagehdlr)->warningbuffer = NULL;
304  (*messagehdlr)->dialogbuffer = NULL;
305  (*messagehdlr)->infobuffer = NULL;
306  (*messagehdlr)->warningbufferlen = 0;
307  (*messagehdlr)->dialogbufferlen = 0;
308  (*messagehdlr)->infobufferlen = 0;
309  (*messagehdlr)->nuses = 1;
310 
311  (*messagehdlr)->quiet = quiet;
312  messagehdlrOpenLogfile(*messagehdlr, filename);
313 
314  /* allocate buffer for buffered output */
315  if( bufferedoutput )
316  {
317  SCIP_ALLOC( BMSallocMemoryArray(&(*messagehdlr)->warningbuffer, SCIP_MAXSTRLEN) ); /*lint !e506*/
318  SCIP_ALLOC( BMSallocMemoryArray(&(*messagehdlr)->dialogbuffer, SCIP_MAXSTRLEN) ); /*lint !e506*/
319  SCIP_ALLOC( BMSallocMemoryArray(&(*messagehdlr)->infobuffer, SCIP_MAXSTRLEN) ); /*lint !e506*/
320  (*messagehdlr)->warningbuffer[0] = '\0';
321  (*messagehdlr)->dialogbuffer[0] = '\0';
322  (*messagehdlr)->infobuffer[0] = '\0';
323  }
324 
325  return SCIP_OKAY;
326 }
327 
328 /** captures message handler */
330  SCIP_MESSAGEHDLR* messagehdlr /**< message handler, or NULL */
331  )
332 {
333  if( messagehdlr != NULL )
334  ++messagehdlr->nuses;
335 }
336 
337 /** releases message handler */
339  SCIP_MESSAGEHDLR** messagehdlr /**< pointer to the message handler */
340  )
341 {
342  assert(messagehdlr != NULL);
343 
344  if( *messagehdlr == NULL )
345  return SCIP_OKAY;
346 
347  assert((*messagehdlr)->nuses >= 1);
348 
349  /* decrement usage counter */
350  --(*messagehdlr)->nuses;
351 
352  /* the last one turns the light off */
353  if( (*messagehdlr)->nuses == 0 )
354  {
355  SCIP_CALL( messagehdlrFree(messagehdlr) );
356  assert(*messagehdlr == NULL);
357  }
358  else
359  {
360  *messagehdlr = NULL;
361  }
362 
363  return SCIP_OKAY;
364 }
365 
366 /** sets the user data of the message handler */
368  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler; must not be NULL */
369  SCIP_MESSAGEHDLRDATA* messagehdlrdata /**< new message handler data to attach to the handler */
370  )
371 {
372  assert(messagehdlr != NULL);
373 
374  if( messagehdlr == NULL ) /*lint !e774*/
375  return SCIP_INVALIDDATA;
376 
377  messagehdlr->messagehdlrdata = messagehdlrdata;
378 
379  return SCIP_OKAY;
380 }
381 
382 /** sets the log file name for the message handler */
384  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
385  const char* filename /**< log file name where to copy messages into, or NULL */
386  )
387 {
388  assert(messagehdlr != NULL);
389 
390  /* close the old log file if one exists */
391  if( messagehdlr->logfile != NULL )
392  {
393  fclose(messagehdlr->logfile);
394  }
395 
396  /* opens the log file */
397  messagehdlrOpenLogfile(messagehdlr, filename);
398 }
399 
400 /** sets the messages handler to be quiet */
402  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
403  SCIP_Bool quiet /**< should screen messages be suppressed? */
404  )
405 {
406  assert(messagehdlr != NULL);
407 
408  /* flush message buffers in order to not loose information */
409  messagePrintWarning(messagehdlr, NULL);
410  messagePrintDialog(messagehdlr, NULL, NULL);
411  messagePrintInfo(messagehdlr, NULL, NULL);
412 
413  messagehdlr->quiet = quiet;
414 }
415 
416 /** prints a warning message, acting like the printf() command */
418  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
419  const char* formatstr, /**< format string like in printf() function */
420  ... /**< format arguments line in printf() function */
421  )
422 {
423  va_list ap;
424 
425  va_start(ap, formatstr); /*lint !e838*/
426  SCIPmessageVFPrintWarning(messagehdlr, formatstr, ap);
427  va_end(ap);
428 }
429 
430 /** prints a warning message, acting like the vprintf() command */
432  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
433  const char* formatstr, /**< format string like in printf() function */
434  va_list ap /**< variable argument list */
435  )
436 {
437  SCIPmessageVFPrintWarning(messagehdlr, formatstr, ap);
438 }
439 
440 /** prints a warning message, acting like the fprintf() command */
442  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
443  const char* formatstr, /**< format string like in printf() function */
444  ... /**< format arguments line in printf() function */
445  )
446 {
447  va_list ap;
448 
449  va_start(ap, formatstr); /*lint !e838*/
450  SCIPmessageVFPrintWarning(messagehdlr, formatstr, ap);
451  va_end(ap);
452 }
453 
454 /** prints a warning message, acting like the vfprintf() command */
456  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
457  const char* formatstr, /**< format string like in printf() function */
458  va_list ap /**< variable argument list */
459  )
460 {
461  char msg[SCIP_MAXSTRLEN];
462  int n;
463  va_list aq;
464 
465  va_copy(aq, ap); /*lint !e838*/
466 
467  n = vsnprintf(msg, SCIP_MAXSTRLEN, formatstr, ap);
468  if( n < 0 )
469  msg[SCIP_MAXSTRLEN-1] = '\0';
470  else if( n >= SCIP_MAXSTRLEN )
471  {
472  char* bigmsg;
473 #ifndef NDEBUG
474  int m;
475 #endif
476 
477  if( BMSallocMemorySize(&bigmsg, n+1) == NULL )
478  {
479  va_end(aq);
480  return;
481  }
482 
483 #ifndef NDEBUG
484  m = vsnprintf(bigmsg, (size_t) n+1, formatstr, aq); /*lint !e571*/
485 #else
486  vsnprintf(bigmsg, (size_t) n+1, formatstr, aq); /*lint !e571*/
487 #endif
488  assert(m == n);
489  va_end(aq);
490  messagePrintWarning(messagehdlr, bigmsg);
491  BMSfreeMemory(&bigmsg);
492  return;
493  }
494 
495  messagePrintWarning(messagehdlr, msg);
496  va_end(aq);
497 }
498 
499 /** prints a dialog message that requests user interaction, acting like the printf() command */
501  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
502  const char* formatstr, /**< format string like in printf() function */
503  ... /**< format arguments line in printf() function */
504  )
505 {
506  va_list ap;
507 
508  va_start(ap, formatstr); /*lint !e838*/
509  SCIPmessageVFPrintDialog(messagehdlr, NULL, formatstr, ap);
510  va_end(ap);
511 }
512 
513 /** prints a dialog message that requests user interaction, acting like the vprintf() command */
515  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
516  const char* formatstr, /**< format string like in printf() function */
517  va_list ap /**< variable argument list */
518  )
519 {
520  SCIPmessageVFPrintDialog(messagehdlr, NULL, formatstr, ap);
521 }
522 
523 /** prints a dialog message that requests user interaction into a file, acting like the fprintf() command */
525  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
526  FILE* file, /**< file stream to print into, or NULL for stdout */
527  const char* formatstr, /**< format string like in printf() function */
528  ... /**< format arguments line in printf() function */
529  )
530 {
531  va_list ap;
532 
533  va_start(ap, formatstr); /*lint !e838*/
534  SCIPmessageVFPrintDialog(messagehdlr, file, formatstr, ap);
535  va_end(ap);
536 }
537 
538 /** prints a dialog message that requests user interaction into a file, acting like the vfprintf() command */
540  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
541  FILE* file, /**< file stream to print into, or NULL for stdout */
542  const char* formatstr, /**< format string like in printf() function */
543  va_list ap /**< variable argument list */
544  )
545 {
546  char msg[SCIP_MAXSTRLEN];
547  int n;
548  va_list aq;
549 
550  va_copy(aq, ap); /*lint !e838*/
551 
552  n = vsnprintf(msg, SCIP_MAXSTRLEN, formatstr, ap);
553  if( n < 0 )
554  msg[SCIP_MAXSTRLEN-1] = '\0';
555  else if( n >= SCIP_MAXSTRLEN )
556  {
557  char* bigmsg;
558 #ifndef NDEBUG
559  int m;
560 #endif
561 
562  if( BMSallocMemorySize(&bigmsg, n+1) == NULL )
563  {
564  va_end(aq);
565  return;
566  }
567 
568 #ifndef NDEBUG
569  m = vsnprintf(bigmsg, (size_t) n+1, formatstr, aq); /*lint !e571*/
570 #else
571  vsnprintf(bigmsg, (size_t) n+1, formatstr, aq); /*lint !e571*/
572 #endif
573  assert(m == n);
574  va_end(aq);
575  messagePrintDialog(messagehdlr, file, bigmsg);
576  BMSfreeMemory(&bigmsg);
577  return;
578  }
579  messagePrintDialog(messagehdlr, file, msg);
580  va_end(aq);
581 }
582 
583 /** prints a message, acting like the printf() command */
585  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
586  const char* formatstr, /**< format string like in printf() function */
587  ... /**< format arguments line in printf() function */
588  )
589 {
590  va_list ap;
591 
592  va_start(ap, formatstr); /*lint !e838*/
593  SCIPmessageVFPrintInfo(messagehdlr, NULL, formatstr, ap);
594  va_end(ap);
595 }
596 
597 /** prints a message, acting like the vprintf() command */
599  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
600  const char* formatstr, /**< format string like in printf() function */
601  va_list ap /**< variable argument list */
602  )
603 {
604  SCIPmessageVFPrintInfo(messagehdlr, NULL, formatstr, ap);
605 }
606 
607 /** prints a message into a file, acting like the fprintf() command */
609  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
610  FILE* file, /**< file stream to print into, or NULL for stdout */
611  const char* formatstr, /**< format string like in printf() function */
612  ... /**< format arguments line in printf() function */
613  )
614 {
615  va_list ap;
616 
617  va_start(ap, formatstr); /*lint !e838*/
618  SCIPmessageVFPrintInfo(messagehdlr, file, formatstr, ap);
619  va_end(ap);
620 }
621 
622 /** prints a message into a file, acting like the vfprintf() command */
624  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
625  FILE* file, /**< file stream to print into, or NULL for stdout */
626  const char* formatstr, /**< format string like in printf() function */
627  va_list ap /**< variable argument list */
628  )
629 {
630  char msg[SCIP_MAXSTRLEN];
631  int n;
632  va_list aq;
633 
634  va_copy(aq, ap); /*lint !e838*/
635 
636  n = vsnprintf(msg, SCIP_MAXSTRLEN, formatstr, ap);
637  if( n < 0 )
638  msg[SCIP_MAXSTRLEN-1] = '\0';
639  else if( n >= SCIP_MAXSTRLEN )
640  {
641  char* bigmsg;
642 #ifndef NDEBUG
643  int m;
644 #endif
645 
646  if( BMSallocMemorySize(&bigmsg, n+1) == NULL )
647  {
648  va_end(aq);
649  return;
650  }
651 
652 #ifndef NDEBUG
653  m = vsnprintf(bigmsg, (size_t) n+1, formatstr, aq); /*lint !e571*/
654 #else
655  vsnprintf(bigmsg, (size_t) n+1, formatstr, aq); /*lint !e571*/
656 #endif
657  assert(m == n);
658  va_end(aq);
659  messagePrintInfo(messagehdlr, file, bigmsg);
660  BMSfreeMemory(&bigmsg);
661  return;
662  }
663  messagePrintInfo(messagehdlr, file, msg);
664  va_end(aq);
665 }
666 
667 /** prints a message depending on the verbosity level, acting like the printf() command */
669  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
670  SCIP_VERBLEVEL verblevel, /**< current verbosity level */
671  SCIP_VERBLEVEL msgverblevel, /**< verbosity level of this message */
672  const char* formatstr, /**< format string like in printf() function */
673  ... /**< format arguments line in printf() function */
674  )
675 {
676  va_list ap;
677 
678  va_start(ap, formatstr); /*lint !e838*/
679  SCIPmessageVFPrintVerbInfo(messagehdlr, verblevel, msgverblevel, NULL, formatstr, ap);
680  va_end(ap);
681 }
682 
683 /** prints a message depending on the verbosity level, acting like the vprintf() command */
685  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
686  SCIP_VERBLEVEL verblevel, /**< current verbosity level */
687  SCIP_VERBLEVEL msgverblevel, /**< verbosity level of this message */
688  const char* formatstr, /**< format string like in printf() function */
689  va_list ap /**< variable argument list */
690  )
691 {
692  SCIPmessageVFPrintVerbInfo(messagehdlr, verblevel, msgverblevel, NULL, formatstr, ap);
693 }
694 
695 /** prints a message into a file depending on the verbosity level, acting like the fprintf() command */
697  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
698  SCIP_VERBLEVEL verblevel, /**< current verbosity level */
699  SCIP_VERBLEVEL msgverblevel, /**< verbosity level of this message */
700  FILE* file, /**< file stream to print into, or NULL for stdout */
701  const char* formatstr, /**< format string like in printf() function */
702  ... /**< format arguments line in printf() function */
703  )
704 {
705  va_list ap;
706 
707  va_start(ap, formatstr); /*lint !e838*/
708  SCIPmessageVFPrintVerbInfo(messagehdlr, verblevel, msgverblevel, file, formatstr, ap);
709  va_end(ap);
710 }
711 
712 /** prints a message into a file depending on the verbosity level, acting like the vfprintf() command */
714  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
715  SCIP_VERBLEVEL verblevel, /**< current verbosity level */
716  SCIP_VERBLEVEL msgverblevel, /**< verbosity level of this message */
717  FILE* file, /**< file stream to print into, or NULL for stdout */
718  const char* formatstr, /**< format string like in printf() function */
719  va_list ap /**< variable argument list */
720  )
721 {
722  assert(msgverblevel > SCIP_VERBLEVEL_NONE);
723  assert(msgverblevel <= SCIP_VERBLEVEL_FULL);
724  assert(verblevel <= SCIP_VERBLEVEL_FULL);
725 
726  if( msgverblevel <= verblevel )
727  {
728  char msg[SCIP_MAXSTRLEN];
729  int n;
730  va_list aq;
731 
732  va_copy(aq, ap); /*lint !e838*/
733 
734  n = vsnprintf(msg, SCIP_MAXSTRLEN, formatstr, ap);
735  if( n < 0 )
736  msg[SCIP_MAXSTRLEN-1] = '\0';
737  else if( n >= SCIP_MAXSTRLEN )
738  {
739  char* bigmsg;
740 #ifndef NDEBUG
741  int m;
742 #endif
743 
744  if( BMSallocMemorySize(&bigmsg, n+1) == NULL )
745  {
746  va_end(aq);
747  return;
748  }
749 
750 #ifndef NDEBUG
751  m = vsnprintf(bigmsg, (size_t) n+1, formatstr, aq); /*lint !e571*/
752 #else
753  vsnprintf(bigmsg, (size_t) n+1, formatstr, aq); /*lint !e571*/
754 #endif
755  assert(m == n);
756  va_end(aq);
757  messagePrintInfo(messagehdlr, file, bigmsg);
758  BMSfreeMemory(&bigmsg);
759  return;
760  }
761  messagePrintInfo(messagehdlr, file, msg);
762  va_end(aq);
763  }
764 }
765 
766 /** prints the header with source file location for an error message using the static message handler */
768  const char* sourcefile, /**< name of the source file that called the function */
769  int sourceline /**< line in the source file where the function was called */
770  )
771 {
772  char msg[SCIP_MAXSTRLEN];
773 
774  /* safe string printing - do not use SCIPsnprintf() since message.c should be independent */
775  (void) snprintf(msg, SCIP_MAXSTRLEN, "[%s:%d] ERROR: ", sourcefile, sourceline);
776  msg[SCIP_MAXSTRLEN-1] = '\0';
777  messagePrintError(NULL, msg);
778 }
779 
780 /** prints a error message, acting like the printf() command */
782  const char* formatstr, /**< format string like in printf() function */
783  ... /**< format arguments line in printf() function */
784  )
785 {
786  va_list ap;
787 
788  va_start(ap, formatstr); /*lint !e838*/
789  SCIPmessageVPrintError(formatstr, ap);
790  va_end(ap);
791 }
792 
793 /** prints an error message, acting like the vprintf() command using the static message handler */
795  const char* formatstr, /**< format string like in printf() function */
796  va_list ap /**< variable argument list */
797  )
798 {
799  char msg[SCIP_MAXSTRLEN];
800  int n;
801  va_list aq;
802 
803  va_copy(aq, ap); /*lint !e838*/
804 
805  n = vsnprintf(msg, SCIP_MAXSTRLEN, formatstr, ap);
806  if( n < 0 )
807  msg[SCIP_MAXSTRLEN-1] = '\0';
808  else if( n >= SCIP_MAXSTRLEN )
809  {
810  char* bigmsg;
811 #ifndef NDEBUG
812  int m;
813 #endif
814 
815  if( BMSallocMemorySize(&bigmsg, n+1) == NULL )
816  {
817  va_end(aq);
818  return;
819  }
820 
821 #ifndef NDEBUG
822  m = vsnprintf(bigmsg, (size_t) n+1, formatstr, aq); /*lint !e571*/
823 #else
824  vsnprintf(bigmsg, (size_t) n+1, formatstr, aq); /*lint !e571*/
825 #endif
826  assert(m == n);
827  va_end(aq);
828  messagePrintError(NULL, bigmsg);
829  BMSfreeMemory(&bigmsg);
830  return;
831  }
832 
833  messagePrintError(NULL, msg);
834  va_end(aq);
835 }
836 
837 /** Method to set the error printing method. Setting the error printing method to NULL will suspend all error methods.
838  *
839  * @note The error printing method is static variable. That means all occurring errors are handled via that methods
840  */
842  SCIP_DECL_ERRORPRINTING((*errorPrinting)),/**< error message print method of message handler, or NULL */
843  void* data /**< data pointer which will be passed to the error printing method, or NULL */
844  )
845 {
846  staticErrorPrinting = errorPrinting;
847  staticErrorPrintingData = data;
848 }
849 
850 /** Method to set the error printing method to default version prints everything the stderr.
851  *
852  * @note The error printing method is a static variable. This means that all occurring errors are handled via this method.
853  */
855  void
856  )
857 {
858  staticErrorPrinting = errorPrintingDefault;
859  staticErrorPrintingData = NULL;
860 }
861 
862 /*
863  * simple functions implemented as defines
864  */
865 
866 /* In debug mode, the following methods are implemented as function calls to ensure
867  * type validity.
868  * In optimized mode, the methods are implemented as defines to improve performance.
869  * However, we want to have them in the library anyways, so we have to undef the defines.
870  */
871 
872 #undef SCIPmessagehdlrGetData
873 #undef SCIPmessagehdlrGetLogfile
874 #undef SCIPmessagehdlrIsQuiet
875 
876 /** returns the user data of the message handler */
878  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
879  )
880 {
881  if( messagehdlr != NULL )
882  return messagehdlr->messagehdlrdata;
883  else
884  return NULL;
885 }
886 
887 
888 /** returns the log file or NULL for stdout */
890  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
891  )
892 {
893  if( messagehdlr == NULL )
894  return NULL;
895 
896  return messagehdlr->logfile;
897 }
898 
899 /** returns TRUE if the message handler is set to be quiet */
901  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
902  )
903 {
904  return (messagehdlr == NULL || messagehdlr->quiet);
905 }
void SCIPmessageVFPrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr, va_list ap)
Definition: message.c:713
SCIP_Bool SCIPmessagehdlrIsQuiet(SCIP_MESSAGEHDLR *messagehdlr)
Definition: message.c:900
#define NULL
Definition: def.h:239
struct SCIP_MessagehdlrData SCIP_MESSAGEHDLRDATA
Definition: type_message.h:51
static void messagePrintError(FILE *file, const char *msg)
Definition: message.c:149
void SCIPmessagePrintErrorHeader(const char *sourcefile, int sourceline)
Definition: message.c:767
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:130
void SCIPmessageFPrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: message.c:696
void SCIPmessageSetErrorPrintingDefault(void)
Definition: message.c:854
#define SCIP_MAXSTRLEN
Definition: def.h:260
#define SCIP_DECL_MESSAGEWARNING(x)
Definition: type_message.h:82
static void messagehdlrOpenLogfile(SCIP_MESSAGEHDLR *messagehdlr, const char *filename)
Definition: message.c:226
static void messagePrintDialog(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *msg)
Definition: message.c:174
static void messagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *msg)
Definition: message.c:160
datastructures for problem statistics
void SCIPmessagehdlrCapture(SCIP_MESSAGEHDLR *messagehdlr)
Definition: message.c:329
SCIP_RETCODE SCIPmessagehdlrCreate(SCIP_MESSAGEHDLR **messagehdlr, SCIP_Bool bufferedoutput, const char *filename, SCIP_Bool quiet, SCIP_DECL_MESSAGEWARNING((*messagewarning)), SCIP_DECL_MESSAGEDIALOG((*messagedialog)), SCIP_DECL_MESSAGEINFO((*messageinfo)), SCIP_DECL_MESSAGEHDLRFREE((*messagehdlrfree)), SCIP_MESSAGEHDLRDATA *messagehdlrdata)
Definition: message.c:285
#define TRUE
Definition: def.h:64
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
enum SCIP_VerbLevel SCIP_VERBLEVEL
Definition: type_message.h:48
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:105
void SCIPmessageVPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr, va_list ap)
Definition: message.c:598
#define BMSfreeMemory(ptr)
Definition: memory.h:127
void SCIPmessageVPrintError(const char *formatstr, va_list ap)
Definition: message.c:794
void SCIPmessagehdlrSetLogfile(SCIP_MESSAGEHDLR *messagehdlr, const char *filename)
Definition: message.c:383
void SCIPmessagePrintError(const char *formatstr,...)
Definition: message.c:781
#define SCIPerrorMessage
Definition: pub_message.h:45
void SCIPmessagePrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr,...)
Definition: message.c:668
#define SCIP_DECL_MESSAGEOUTPUTFUNC(x)
Definition: type_message.h:57
#define va_copy(dest, src)
Definition: message.c:37
static void * staticErrorPrintingData
Definition: message.c:145
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:417
SCIP_RETCODE SCIPmessagehdlrRelease(SCIP_MESSAGEHDLR **messagehdlr)
Definition: message.c:338
void SCIPmessageVPrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr, va_list ap)
Definition: message.c:684
#define SCIP_CALL(x)
Definition: def.h:351
void SCIPmessageFPrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:441
static SCIP_RETCODE messagehdlrFree(SCIP_MESSAGEHDLR **messagehdlr)
Definition: message.c:246
void SCIPmessagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:584
void SCIPmessagePrintDialog(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:500
public data structures and miscellaneous methods
#define SCIP_Bool
Definition: def.h:62
void SCIPmessagehdlrSetQuiet(SCIP_MESSAGEHDLR *messagehdlr, SCIP_Bool quiet)
Definition: message.c:401
#define SCIP_DECL_MESSAGEHDLRFREE(x)
Definition: type_message.h:113
FILE * SCIPmessagehdlrGetLogfile(SCIP_MESSAGEHDLR *messagehdlr)
Definition: message.c:889
static SCIP_DECL_ERRORPRINTING(errorPrintingDefault)
Definition: message.c:129
void SCIPmessageVPrintDialog(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr, va_list ap)
Definition: message.c:514
void SCIPmessageFPrintDialog(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:524
#define SCIP_DECL_MESSAGEDIALOG(x)
Definition: type_message.h:93
void SCIPmessageVFPrintDialog(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr, va_list ap)
Definition: message.c:539
void SCIPmessageVFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr, va_list ap)
Definition: message.c:623
#define BMSallocMemorySize(ptr, size)
Definition: memory.h:102
SCIP_RETCODE SCIPmessagehdlrSetData(SCIP_MESSAGEHDLR *messagehdlr, SCIP_MESSAGEHDLRDATA *messagehdlrdata)
Definition: message.c:367
void SCIPmessageSetErrorPrinting(SCIP_DECL_ERRORPRINTING((*errorPrinting)), void *data)
Definition: message.c:841
public methods for message output
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:608
void SCIPmessageVFPrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr, va_list ap)
Definition: message.c:455
#define BMSallocMemory(ptr)
Definition: memory.h:101
static void messagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *msg)
Definition: message.c:200
static void handleMessage(SCIP_MESSAGEHDLR *messagehdlr, SCIP_DECL_MESSAGEOUTPUTFUNC(outputfunc), FILE *file1, SCIP_Bool usefile1, FILE *file2, SCIP_Bool usefile2, const char *msg, char *buffer, int *bufferlen)
Definition: message.c:48
void SCIPmessageVPrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr, va_list ap)
Definition: message.c:431
SCIP_MESSAGEHDLRDATA * messagehdlrdata
common defines and data types used in all packages of SCIP
SCIP_MESSAGEHDLRDATA * SCIPmessagehdlrGetData(SCIP_MESSAGEHDLR *messagehdlr)
Definition: message.c:877
#define SCIP_ALLOC(x)
Definition: def.h:362
#define SCIP_DECL_MESSAGEINFO(x)
Definition: type_message.h:104
memory allocation routines