1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2 /* */ 3 /* This file is part of the class library */ 4 /* SoPlex --- the Sequential object-oriented simPlex. */ 5 /* */ 6 /* Copyright (c) 1996-2023 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 SoPlex; see the file LICENSE. If not email to soplex@zib.de. */ 22 /* */ 23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 24 25 /**@file mpsinput.h 26 * @brief Read MPS format files. 27 */ 28 #ifndef _MPSINPUT_H_ 29 #define _MPSINPUT_H_ 30 31 #include <iostream> 32 33 #include "soplex/spxout.h" 34 35 namespace soplex 36 { 37 38 /**@class MPSInput 39 40 Reads MPS input files. A right-hand side for the objective function is 41 allowed but ignored. 42 */ 43 class MPSInput 44 { 45 public: 46 47 //----------------------------------- 48 /**@name Types */ 49 ///@{ 50 /// 51 52 enum Section 53 { 54 NAME, OBJSEN, OBJNAME, ROWS, COLUMNS, RHS, RANGES, BOUNDS, ENDATA 55 }; 56 /// 57 58 /// optimization sense. 59 enum Sense 60 { 61 MAXIMIZE = 1, 62 MINIMIZE = -1 63 }; 64 65 enum { MAX_LINE_LEN = 256 }; 66 67 ///@} 68 69 private: 70 71 //----------------------------------- 72 /**@name Private data */ 73 ///@{ 74 /// 75 Section m_section; 76 /// the input stream from which the file is read 77 std::istream& m_input; 78 /// line number 79 int m_lineno; 80 /// objctive sense (maximization or minimization) 81 Sense m_objsense; 82 /// is set to \c true upon a syntax error 83 bool m_has_error; 84 /// the line buffer 85 char m_buf[MAX_LINE_LEN]; 86 /// first field in a line 87 const char* m_f0; 88 /// second field in a line 89 const char* m_f1; 90 /// third field in a line 91 const char* m_f2; 92 /// fourth field in a line 93 const char* m_f3; 94 /// fifth field in a line 95 const char* m_f4; 96 /// sixth field in a line 97 const char* m_f5; 98 /// problem name 99 char m_probname[MAX_LINE_LEN]; 100 /// objective name 101 char m_objname [MAX_LINE_LEN]; 102 /// 103 bool m_is_integer; 104 /// new MPS format? 105 bool m_is_new_format; 106 /// Number of already ignored entries. 107 int m_ignored; 108 /// Maximal number of ignored entries for which a warning will be issued. 109 static const int m_max_ignore = 1000; 110 ///@} 111 112 public: 113 114 //----------------------------------- 115 /**@name Construction / destruction */ 116 ///@{ 117 /// 118 explicit 119 MPSInput(std::istream& p_input) 120 : m_section(NAME) 121 , m_input(p_input) 122 , m_lineno(0) 123 , m_objsense(MPSInput::MINIMIZE) 124 , m_has_error(false) 125 , m_is_integer(false) 126 , m_is_new_format(false) 127 , m_ignored(0) 128 { 129 m_f0 = m_f1 = m_f2 = m_f3 = m_f4 = m_f5 = 0; 130 131 m_buf [0] = '\0'; 132 m_probname[0] = '\0'; 133 m_objname [0] = '\0'; 134 } 135 /// 136 virtual 137 ~MPSInput() 138 { 139 // only to signal to flexelint that the pointers do 140 // not point to anything that has to be freed. 141 m_f0 = m_f1 = m_f2 = m_f3 = m_f4 = m_f5 = 0; 142 } 143 ///@} 144 145 //----------------------------------- 146 /**@name Access */ 147 ///@{ 148 /// 149 Section section() const 150 { 151 return m_section; 152 } 153 /// 154 int lineno() const 155 { 156 return m_lineno; 157 } 158 /// 159 const char* field0() const 160 { 161 return m_f0; 162 } 163 /// 164 const char* field1() const 165 { 166 return m_f1; 167 } 168 /// 169 const char* field2() const 170 { 171 return m_f2; 172 } 173 /// 174 const char* field3() const 175 { 176 return m_f3; 177 } 178 /// 179 const char* field4() const 180 { 181 return m_f4; 182 } 183 /// 184 const char* field5() const 185 { 186 return m_f5; 187 } 188 /// 189 const char* probName() const 190 { 191 return m_probname; 192 } 193 /// 194 const char* objName() const 195 { 196 return m_objname; 197 } 198 /// 199 Sense objSense() const 200 { 201 return m_objsense; 202 } 203 /// 204 bool hasError() const 205 { 206 return m_has_error; 207 } 208 /// 209 bool isInteger() const 210 { 211 return m_is_integer; 212 } 213 ///@} 214 215 //----------------------------------- 216 /**@name Modification */ 217 ///@{ 218 /// 219 void setSection(Section p_section) 220 { 221 m_section = p_section; 222 } 223 /// 224 void setProbName(const char* p_probname) 225 { 226 assert(strlen(p_probname) < MAX_LINE_LEN); 227 spxSnprintf(m_probname, MAX_LINE_LEN, "%s", p_probname); 228 } 229 /// 230 void setObjName(const char* p_objname) 231 { 232 assert(strlen(p_objname) < MAX_LINE_LEN); 233 spxSnprintf(m_objname, MAX_LINE_LEN, "%s", p_objname); 234 } 235 /// 236 void setObjSense(Sense sense) 237 { 238 m_objsense = sense; 239 } 240 ///@} 241 242 //----------------------------------- 243 /**@name Warnings and Errors */ 244 ///@{ 245 /// 246 void syntaxError() 247 { 248 SPX_MSG_ERROR(std::cerr << "Syntax error in line " << m_lineno << std::endl;) 249 m_section = ENDATA; 250 m_has_error = true; 251 } 252 /// 253 void entryIgnored( 254 const char* what, const char* what_name, 255 const char* entity, const char* entity_name) 256 { 257 if(m_ignored < m_max_ignore) 258 { 259 SPX_MSG_ERROR(std::cerr << "Warning: line " << m_lineno << ": " 260 << what << " \"" << what_name << "\"" 261 << " for " << entity << " \"" 262 << entity_name << "\" ignored" << std::endl;) 263 ++m_ignored; 264 265 if(m_ignored == m_max_ignore) 266 SPX_MSG_ERROR(std::cerr << "Warning: This was the " << m_max_ignore 267 << " ignored entry. No further warnings on " 268 << "ignored entries will be given." << std::endl;) 269 } 270 } 271 ///@} 272 273 //----------------------------------- 274 /**@name Helpers */ 275 ///@{ 276 /// reads an MPS format data line and parse the fields. 277 bool readLine(); 278 /// Inserts \p name as field 1 and shifts all other fields up. 279 void insertName(const char* name, 280 bool second = false); 281 ///@} 282 }; 283 } // namespace soplex 284 #endif // _MPSINPUT_H_ 285