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