1 /* Frobby: Software for monomial ideal computations.
2    Copyright (C) 2007 Bjarke Hammersholt Roune (www.broune.com)
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see http://www.gnu.org/licenses/.
16 */
17 #include "stdinc.h"
18 #include "IOParameters.h"
19 
20 #include "IOFacade.h"
21 #include "Macaulay2IOHandler.h"
22 #include "Scanner.h"
23 #include "error.h"
24 #include "FrobbyStringStream.h"
25 #include "DataType.h"
26 
IOParameters(const DataType & input,const DataType & output)27 IOParameters::IOParameters(const DataType& input, const DataType& output):
28   _inputType(input),
29   _outputType(output),
30   _inputFormat(0),
31   _outputFormat(0) {
32 
33   string inputFormats;
34   string outputFormats;
35 
36   string defaultOutput;
37   if (!_inputType.isNull())
38     defaultOutput = getFormatNameIndicatingToUseInputFormatAsOutputFormat();
39   else {
40     defaultOutput = IO::Macaulay2IOHandler::staticGetName();
41     ASSERT(createIOHandler(defaultOutput)->supportsOutput(_outputType));
42   }
43 
44   vector<string> names;
45   getIOHandlerNames(names);
46   for (vector<string>::const_iterator name = names.begin();
47        name != names.end(); ++name) {
48     auto_ptr<IOHandler> handler = createIOHandler(*name);
49     ASSERT(handler.get() != 0);
50 
51     if (handler->supportsInput(_inputType)) {
52       inputFormats += ' ';
53       inputFormats += handler->getName();
54     }
55     if (handler->supportsOutput(_outputType)) {
56       outputFormats += ' ';
57       outputFormats += handler->getName();
58     }
59   }
60 
61   if (!_inputType.isNull()) {
62     string desc =
63       "The format used to read the input. "
64       "This action supports the formats:\n " + inputFormats + ".\n"
65       "The format \"" +
66       getFormatNameIndicatingToGuessTheInputFormat() +
67       "\" instructs Frobby to guess the format.\n"
68       "Type 'frobby help io' for more information on input formats.";
69 
70     _inputFormat.reset
71       (new StringParameter
72        ("iformat", desc.c_str(),
73         getFormatNameIndicatingToGuessTheInputFormat()));
74     addParameter(_inputFormat.get());
75   }
76 
77   if (!output.isNull()) {
78     string desc =
79       "The format used to write the output. "
80       "This action supports the formats:\n " + outputFormats + ".\n";
81     if (!_inputType.isNull()) {
82       desc +=
83         "The format \"" +
84         getFormatNameIndicatingToUseInputFormatAsOutputFormat()
85         + "\" instructs Frobby to use the input format.\n";
86     }
87     desc += "Type 'frobby help io' for more information on output formats.";
88 
89     _outputFormat.reset
90       (new StringParameter("oformat", desc.c_str(), defaultOutput));
91     addParameter(_outputFormat.get());
92   }
93 }
94 
setOutputFormat(const string & format)95 void IOParameters::setOutputFormat(const string& format) {
96   ASSERT(!_inputType.isNull());
97   ASSERT(_outputFormat.get() != 0);
98 
99   *_outputFormat = format;
100 }
101 
setInputFormat(const string & format)102 void IOParameters::setInputFormat(const string& format) {
103   ASSERT(!_outputType.isNull());
104 
105   *_inputFormat = format;
106 }
107 
getInputFormat() const108 const string& IOParameters::getInputFormat() const {
109   ASSERT(!_inputType.isNull());
110   ASSERT(_inputFormat.get() != 0);
111 
112   return *_inputFormat;
113 }
114 
getOutputFormat() const115 const string& IOParameters::getOutputFormat() const {
116   ASSERT(!_outputType.isNull());
117   ASSERT(_outputFormat.get() != 0);
118 
119   if (!_inputType.isNull() &&
120       _outputFormat->getValue() ==
121       getFormatNameIndicatingToUseInputFormatAsOutputFormat()) {
122     ASSERT(_inputFormat.get() != 0);
123     return *_inputFormat;
124   }
125 
126   return *_outputFormat;
127 }
128 
createInputHandler() const129 auto_ptr<IOHandler> IOParameters::createInputHandler() const {
130   auto_ptr<IOHandler> handler(createIOHandler(getInputFormat()));
131   ASSERT(handler.get() != 0);
132   return handler;
133 }
134 
createOutputHandler() const135 auto_ptr<IOHandler> IOParameters::createOutputHandler() const {
136   auto_ptr<IOHandler> handler(createIOHandler(getOutputFormat()));
137   ASSERT(handler.get() != 0);
138   return handler;
139 }
140 
autoDetectInputFormat(Scanner & in)141 void IOParameters::autoDetectInputFormat(Scanner& in) {
142   ASSERT(!_inputType.isNull());
143   ASSERT(_inputFormat.get() != 0);
144 
145   if (_inputFormat->getValue() ==
146       getFormatNameIndicatingToGuessTheInputFormat())
147     *_inputFormat = autoDetectFormat(in);
148 
149   if (in.getFormat() ==
150       getFormatNameIndicatingToGuessTheInputFormat())
151     in.setFormat(*_inputFormat);
152 }
153 
validateFormats() const154 void IOParameters::validateFormats() const {
155   IOFacade facade(false);
156 
157   if (!_inputType.isNull()) {
158     auto_ptr<IOHandler> handler(createIOHandler(getInputFormat()));
159 
160     if (!handler->supportsInput(_inputType)) {
161       FrobbyStringStream errorMsg;
162       errorMsg << "The "
163                << handler->getName()
164                << " format does not support input of "
165                << _inputType.getName()
166                << '.';
167       reportError(errorMsg);
168     }
169   }
170 
171   if (!_outputType.isNull()) {
172     auto_ptr<IOHandler> handler(createIOHandler(getOutputFormat()));
173     /*
174     if (!handler->supportsOutput(_outputType)) {
175       FrobbyStringStream errorMsg;
176       errorMsg << "The "
177                << handler->getName()
178                << " format does not support output of "
179                << _outputType.getName()
180                << '.';
181       reportError(errorMsg);
182     }
183     */
184   }
185 }
186