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