1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the HiGHS linear optimization suite */
4 /* */
5 /* Written and engineered 2008-2021 at the University of Edinburgh */
6 /* */
7 /* Available as open-source under the MIT License */
8 /* */
9 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
10 /**@file io/HighsIO.cpp
11 * @brief IO methods for HiGHS - currently just print/log messages
12 * @author Julian Hall, Ivet Galabova, Qi Huangfu and Michael Feldmeier
13 */
14 #include "HighsIO.h"
15
16 #include <cstdarg>
17 #include <cstdio>
18 #include <ctime>
19
20 #include "lp_data/HighsLp.h"
21 #include "lp_data/HighsOptions.h"
22
23 void (*printmsgcb)(int, const char*, void*) = NULL;
24 void (*logmsgcb)(HighsMessageType, const char*, void*) = NULL;
25 void* msgcb_data = NULL;
26
27 char msgbuffer[65536];
28
HighsPrintMessage(FILE * pass_output,const int pass_message_level,const int level,const char * format,...)29 void HighsPrintMessage(FILE* pass_output, const int pass_message_level,
30 const int level, const char* format, ...) {
31 if (pass_output == NULL) {
32 return;
33 }
34 if (pass_message_level & level) {
35 va_list argptr;
36 va_start(argptr, format);
37 if (printmsgcb == NULL)
38 vfprintf(pass_output, format, argptr);
39 else {
40 int len;
41 len = vsnprintf(msgbuffer, sizeof(msgbuffer), format, argptr);
42 if (len >= (int)sizeof(msgbuffer)) {
43 // Output was truncated: for now just ensure string is null-terminated
44 msgbuffer[sizeof(msgbuffer) - 1] = '\0';
45 }
46 printmsgcb(level, msgbuffer, msgcb_data);
47 }
48 va_end(argptr);
49 }
50 }
51
HighsLogMessage(FILE * pass_logfile,HighsMessageType type,const char * format,...)52 void HighsLogMessage(FILE* pass_logfile, HighsMessageType type,
53 const char* format, ...) {
54 if (pass_logfile == NULL) {
55 return;
56 }
57
58 time_t rawtime;
59 struct tm* timeinfo;
60
61 time(&rawtime);
62 timeinfo = localtime(&rawtime);
63 va_list argptr;
64 va_start(argptr, format);
65
66 if (logmsgcb == NULL) {
67 fprintf(pass_logfile, "%-7s: ", HighsMessageTypeTag[(int)type]);
68 vfprintf(pass_logfile, format, argptr);
69 fprintf(pass_logfile, "\n");
70 } else {
71 int len;
72 len = snprintf(msgbuffer, sizeof(msgbuffer), "%02d:%02d:%02d [%-7s] ",
73 timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec,
74 HighsMessageTypeTag[(int)type]);
75 if (len < (int)sizeof(msgbuffer))
76 len +=
77 vsnprintf(msgbuffer + len, sizeof(msgbuffer) - len, format, argptr);
78 if (len < (int)sizeof(msgbuffer) - 1) {
79 msgbuffer[len] = '\n';
80 ++len;
81 msgbuffer[len] = '\0';
82 } else
83 msgbuffer[sizeof(msgbuffer) - 1] = '\0';
84 logmsgcb(type, msgbuffer, msgcb_data);
85 }
86
87 va_end(argptr);
88 }
89
HighsSetMessageCallback(void (* printmsgcb_)(int level,const char * msg,void * msgcb_data),void (* logmsgcb_)(HighsMessageType type,const char * msg,void * msgcb_data),void * msgcb_data_)90 void HighsSetMessageCallback(
91 void (*printmsgcb_)(int level, const char* msg, void* msgcb_data),
92 void (*logmsgcb_)(HighsMessageType type, const char* msg, void* msgcb_data),
93 void* msgcb_data_) {
94 printmsgcb = printmsgcb_;
95 logmsgcb = logmsgcb_;
96 msgcb_data = msgcb_data_;
97 }
98
HighsSetIO(HighsOptions & options)99 void HighsSetIO(HighsOptions& options) {
100 printmsgcb = options.printmsgcb;
101 logmsgcb = options.logmsgcb;
102 msgcb_data = options.msgcb_data;
103 }
104