1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2 /* */ 3 /* This file is part of the program and library */ 4 /* SCIP --- Solving Constraint Integer Programs */ 5 /* */ 6 /* Copyright (c) 2002-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 SCIP; see the file LICENSE. If not visit scipopt.org. */ 22 /* */ 23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 24 25 /**@file scip_reader.c 26 * @ingroup OTHER_CFILES 27 * @brief public methods for reader plugins 28 * @author Tobias Achterberg 29 * @author Timo Berthold 30 * @author Gerald Gamrath 31 * @author Leona Gottwald 32 * @author Stefan Heinz 33 * @author Gregor Hendel 34 * @author Thorsten Koch 35 * @author Alexander Martin 36 * @author Marc Pfetsch 37 * @author Michael Winkler 38 * @author Kati Wolter 39 * 40 * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE 41 */ 42 43 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/ 44 45 #include "scip/debug.h" 46 #include "scip/pub_message.h" 47 #include "scip/reader.h" 48 #include "scip/scip_reader.h" 49 #include "scip/set.h" 50 #include "scip/struct_scip.h" 51 #include "scip/struct_set.h" 52 53 /** creates a reader and includes it in SCIP 54 * 55 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 56 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 57 * 58 * @pre This method can be called if SCIP is in one of the following stages: 59 * - \ref SCIP_STAGE_INIT 60 * - \ref SCIP_STAGE_PROBLEM 61 * 62 * @note method has all reader callbacks as arguments and is thus changed every time a new callback is added 63 * in future releases; consider using SCIPincludeReaderBasic() and setter functions 64 * if you seek for a method which is less likely to change in future releases 65 */ 66 SCIP_RETCODE SCIPincludeReader( 67 SCIP* scip, /**< SCIP data structure */ 68 const char* name, /**< name of reader */ 69 const char* desc, /**< description of reader */ 70 const char* extension, /**< file extension that reader processes */ 71 SCIP_DECL_READERCOPY ((*readercopy)), /**< copy method of reader or NULL if you don't want to copy your plugin into sub-SCIPs */ 72 SCIP_DECL_READERFREE ((*readerfree)), /**< destructor of reader */ 73 SCIP_DECL_READERREAD ((*readerread)), /**< read method */ 74 SCIP_DECL_READERWRITE ((*readerwrite)), /**< write method */ 75 SCIP_READERDATA* readerdata /**< reader data */ 76 ) 77 { 78 SCIP_READER* reader; 79 80 SCIP_CALL( SCIPcheckStage(scip, "SCIPincludeReader", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 81 82 /* check whether reader is already present */ 83 if( SCIPfindReader(scip, name) != NULL ) 84 { 85 SCIPerrorMessage("reader <%s> already included.\n", name); 86 return SCIP_INVALIDDATA; 87 } 88 89 SCIP_CALL( SCIPreaderCreate(&reader, scip->set, name, desc, extension, readercopy, readerfree, readerread, 90 readerwrite, readerdata) ); 91 SCIP_CALL( SCIPsetIncludeReader(scip->set, reader) ); 92 93 return SCIP_OKAY; 94 } 95 96 /** creates a reader and includes it in SCIP. All non-fundamental (or optional) callbacks will be set to NULL. 97 * Optional callbacks can be set via specific setter functions, see 98 * SCIPsetReaderCopy(), SCIPsetReaderFree(), SCIPsetReaderRead(), SCIPsetReaderWrite(). 99 * 100 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 101 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 102 * 103 * @pre This method can be called if SCIP is in one of the following stages: 104 * - \ref SCIP_STAGE_INIT 105 * - \ref SCIP_STAGE_PROBLEM 106 * 107 * @note if you want to set all callbacks with a single method call, consider using SCIPincludeReader() instead 108 */ 109 SCIP_RETCODE SCIPincludeReaderBasic( 110 SCIP* scip, /**< SCIP data structure */ 111 SCIP_READER** readerptr, /**< reference to reader pointer, or NULL */ 112 const char* name, /**< name of reader */ 113 const char* desc, /**< description of reader */ 114 const char* extension, /**< file extension that reader processes */ 115 SCIP_READERDATA* readerdata /**< reader data */ 116 ) 117 { 118 SCIP_READER* reader; 119 120 SCIP_CALL( SCIPcheckStage(scip, "SCIPincludeReaderBasic", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 121 122 /* check whether reader is already present */ 123 if( SCIPfindReader(scip, name) != NULL ) 124 { 125 SCIPerrorMessage("reader <%s> already included.\n", name); 126 return SCIP_INVALIDDATA; 127 } 128 129 SCIP_CALL( SCIPreaderCreate(&reader, scip->set, name, desc, extension, NULL, NULL, NULL, NULL, readerdata) ); 130 SCIP_CALL( SCIPsetIncludeReader(scip->set, reader) ); 131 132 if( readerptr != NULL ) 133 *readerptr = reader; 134 135 return SCIP_OKAY; 136 } 137 138 /** set copy method of reader 139 * 140 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 141 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 142 * 143 * @pre This method can be called if SCIP is in one of the following stages: 144 * - \ref SCIP_STAGE_INIT 145 * - \ref SCIP_STAGE_PROBLEM 146 */ 147 SCIP_RETCODE SCIPsetReaderCopy( 148 SCIP* scip, /**< SCIP data structure */ 149 SCIP_READER* reader, /**< reader */ 150 SCIP_DECL_READERCOPY ((*readercopy)) /**< copy method of reader or NULL if you don't want to copy your plugin into sub-SCIPs */ 151 ) 152 { 153 assert(scip != NULL); 154 155 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetReaderCopy", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 156 157 SCIPreaderSetCopy(reader, readercopy); 158 159 return SCIP_OKAY; 160 } 161 162 /** set deinitialization method of reader 163 * 164 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 165 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 166 * 167 * @pre This method can be called if SCIP is in one of the following stages: 168 * - \ref SCIP_STAGE_INIT 169 * - \ref SCIP_STAGE_PROBLEM 170 */ 171 SCIP_RETCODE SCIPsetReaderFree( 172 SCIP* scip, /**< SCIP data structure */ 173 SCIP_READER* reader, /**< reader */ 174 SCIP_DECL_READERFREE ((*readerfree)) /**< destructor of reader */ 175 ) 176 { 177 assert(scip != NULL); 178 179 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetReaderFree", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 180 181 SCIPreaderSetFree(reader, readerfree); 182 183 return SCIP_OKAY; 184 } 185 186 /** set read method of reader 187 * 188 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 189 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 190 * 191 * @pre This method can be called if SCIP is in one of the following stages: 192 * - \ref SCIP_STAGE_INIT 193 * - \ref SCIP_STAGE_PROBLEM 194 */ 195 SCIP_RETCODE SCIPsetReaderRead( 196 SCIP* scip, /**< SCIP data structure */ 197 SCIP_READER* reader, /**< reader */ 198 SCIP_DECL_READERREAD ((*readerread)) /**< read method of reader */ 199 ) 200 { 201 assert(scip != NULL); 202 203 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetReaderRead", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 204 205 SCIPreaderSetRead(reader, readerread); 206 207 return SCIP_OKAY; 208 } 209 210 /** set write method of reader 211 * 212 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 213 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 214 * 215 * @pre This method can be called if SCIP is in one of the following stages: 216 * - \ref SCIP_STAGE_INIT 217 * - \ref SCIP_STAGE_PROBLEM 218 */ 219 SCIP_RETCODE SCIPsetReaderWrite( 220 SCIP* scip, /**< SCIP data structure */ 221 SCIP_READER* reader, /**< reader */ 222 SCIP_DECL_READERWRITE ((*readerwrite)) /**< write method of reader */ 223 ) 224 { 225 assert(scip != NULL); 226 227 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetReaderWrite", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 228 229 SCIPreaderSetWrite(reader, readerwrite); 230 231 return SCIP_OKAY; 232 } 233 234 /** returns the reader of the given name, or NULL if not existing */ 235 SCIP_READER* SCIPfindReader( 236 SCIP* scip, /**< SCIP data structure */ 237 const char* name /**< name of reader */ 238 ) 239 { 240 assert(scip != NULL); 241 assert(scip->set != NULL); 242 assert(name != NULL); 243 244 return SCIPsetFindReader(scip->set, name); 245 } 246 247 /** returns the array of currently available readers */ 248 SCIP_READER** SCIPgetReaders( 249 SCIP* scip /**< SCIP data structure */ 250 ) 251 { 252 assert(scip != NULL); 253 assert(scip->set != NULL); 254 255 return scip->set->readers; 256 } 257 258 /** returns the number of currently available readers */ 259 int SCIPgetNReaders( 260 SCIP* scip /**< SCIP data structure */ 261 ) 262 { 263 assert(scip != NULL); 264 assert(scip->set != NULL); 265 266 return scip->set->nreaders; 267 } 268