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