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-2024 Zuse Institute Berlin (ZIB) */
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"
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(_MSC_VER) && _MSC_VER < 1900
52#define snprintf _snprintf
53#define vsnprintf _vsnprintf
54#endif
55
56/** handles the output of the given message */
57static
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 */
138static
139SCIP_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 */
152static 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 */
158static
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 */
169static
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 */
183static
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 */
209static
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 */
235static
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 */
255static
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';
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
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;
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;
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}
common defines and data types used in all packages of SCIP
#define NULL
Definition: def.h:267
#define SCIP_MAXSTRLEN
Definition: def.h:288
#define SCIP_Bool
Definition: def.h:91
#define SCIP_ALLOC(x)
Definition: def.h:385
#define TRUE
Definition: def.h:93
#define SCIP_CALL(x)
Definition: def.h:374
memory allocation routines
#define BMSfreeMemory(ptr)
Definition: memory.h:145
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:123
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:148
#define BMSallocMemorySize(ptr, size)
Definition: memory.h:120
#define BMSallocMemory(ptr)
Definition: memory.h:118
void SCIPmessagePrintError(const char *formatstr,...)
Definition: message.c:791
#define va_copy(dest, src)
Definition: message.c:47
static void messagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *msg)
Definition: message.c:210
void SCIPmessageVPrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr, va_list ap)
Definition: message.c:694
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
void SCIPmessageFPrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:451
void SCIPmessageVPrintDialog(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr, va_list ap)
Definition: message.c:524
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
static SCIP_DECL_ERRORPRINTING(errorPrintingDefault)
Definition: message.c:139
static void messagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *msg)
Definition: message.c:170
SCIP_MESSAGEHDLRDATA * SCIPmessagehdlrGetData(SCIP_MESSAGEHDLR *messagehdlr)
Definition: message.c:887
static SCIP_RETCODE messagehdlrFree(SCIP_MESSAGEHDLR **messagehdlr)
Definition: message.c:256
void SCIPmessageFPrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: message.c:706
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:618
static void * staticErrorPrintingData
Definition: message.c:155
void SCIPmessageVFPrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr, va_list ap)
Definition: message.c:465
void SCIPmessageVFPrintDialog(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr, va_list ap)
Definition: message.c:549
void SCIPmessagehdlrSetLogfile(SCIP_MESSAGEHDLR *messagehdlr, const char *filename)
Definition: message.c:393
static void messagehdlrOpenLogfile(SCIP_MESSAGEHDLR *messagehdlr, const char *filename)
Definition: message.c:236
void SCIPmessageVFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr, va_list ap)
Definition: message.c:633
void SCIPmessageSetErrorPrinting(SCIP_DECL_ERRORPRINTING((*errorPrinting)), void *data)
Definition: message.c:851
void SCIPmessagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:594
void SCIPmessageVPrintError(const char *formatstr, va_list ap)
Definition: message.c:804
void SCIPmessagePrintDialog(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:510
SCIP_RETCODE SCIPmessagehdlrRelease(SCIP_MESSAGEHDLR **messagehdlr)
Definition: message.c:348
void SCIPmessageVFPrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr, va_list ap)
Definition: message.c:723
void SCIPmessagehdlrSetQuiet(SCIP_MESSAGEHDLR *messagehdlr, SCIP_Bool quiet)
Definition: message.c:411
void SCIPmessageVPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr, va_list ap)
Definition: message.c:608
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:427
SCIP_Bool SCIPmessagehdlrIsQuiet(SCIP_MESSAGEHDLR *messagehdlr)
Definition: message.c:910
static void messagePrintDialog(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *msg)
Definition: message.c:184
FILE * SCIPmessagehdlrGetLogfile(SCIP_MESSAGEHDLR *messagehdlr)
Definition: message.c:899
SCIP_RETCODE SCIPmessagehdlrSetData(SCIP_MESSAGEHDLR *messagehdlr, SCIP_MESSAGEHDLRDATA *messagehdlrdata)
Definition: message.c:377
void SCIPmessageVPrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr, va_list ap)
Definition: message.c:441
void SCIPmessagehdlrCapture(SCIP_MESSAGEHDLR *messagehdlr)
Definition: message.c:339
void SCIPmessageSetErrorPrintingDefault(void)
Definition: message.c:864
void SCIPmessagePrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr,...)
Definition: message.c:678
void SCIPmessageFPrintDialog(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:534
static void messagePrintError(FILE *file, const char *msg)
Definition: message.c:159
void SCIPmessagePrintErrorHeader(const char *sourcefile, int sourceline)
Definition: message.c:777
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
public data structures and miscellaneous methods
SCIP_MESSAGEHDLRDATA * messagehdlrdata
datastructures for problem statistics
#define SCIP_DECL_MESSAGEOUTPUTFUNC(x)
Definition: type_message.h:68
#define SCIP_DECL_MESSAGEWARNING(x)
Definition: type_message.h:93
#define SCIP_DECL_MESSAGEINFO(x)
Definition: type_message.h:115
#define SCIP_DECL_MESSAGEDIALOG(x)
Definition: type_message.h:104
enum SCIP_VerbLevel SCIP_VERBLEVEL
Definition: type_message.h:59
#define SCIP_DECL_MESSAGEHDLRFREE(x)
Definition: type_message.h:124
@ SCIP_VERBLEVEL_NONE
Definition: type_message.h:52
@ SCIP_VERBLEVEL_FULL
Definition: type_message.h:57
struct SCIP_MessagehdlrData SCIP_MESSAGEHDLRDATA
Definition: type_message.h:62
@ SCIP_INVALIDDATA
Definition: type_retcode.h:52
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63