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-2025 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:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_ALLOC(x)
    Definition: def.h:366
    #define TRUE
    Definition: def.h:93
    #define SCIP_CALL(x)
    Definition: def.h:355
    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:73
    #define SCIP_DECL_MESSAGEWARNING(x)
    Definition: type_message.h:98
    #define SCIP_DECL_MESSAGEINFO(x)
    Definition: type_message.h:120
    #define SCIP_DECL_MESSAGEDIALOG(x)
    Definition: type_message.h:109
    enum SCIP_VerbLevel SCIP_VERBLEVEL
    Definition: type_message.h:64
    #define SCIP_DECL_MESSAGEHDLRFREE(x)
    Definition: type_message.h:129
    @ SCIP_VERBLEVEL_NONE
    Definition: type_message.h:57
    @ SCIP_VERBLEVEL_FULL
    Definition: type_message.h:62
    struct SCIP_MessagehdlrData SCIP_MESSAGEHDLRDATA
    Definition: type_message.h:67
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63