OSDN Git Service

5898a8540d9da58c445907d2c18d3add89ad7a26
[qcad/qcad.git] / compiler / qcrun.cpp
1 //----------------------------------------------------------------------------\r
2 //  qcrun.cpp\r
3 //  Interpreter for ntermediate code\r
4 //  $Date: 2003/02/20 00:24:16 $\r
5 //  $Revision: 1.8 $\r
6 //----------------------------------------------------------------------------\r
7 #include <iostream>\r
8 #include <iomanip>\r
9 #include <fstream>\r
10 #include <cstdlib>\r
11 #include <vector>\r
12 #include <string>\r
13 \r
14 #include "QBits.h"\r
15 #include "QCompilerCntl.h"\r
16 #include "QCalcUnit.h"\r
17 \r
18 typedef unsigned int                Appoptions;\r
19 typedef std::vector<QCalcUnit *>    QCalcUnits;\r
20 \r
21 const char * const  app_name        = "qcrun";\r
22 const char * const  app_version     = "1.0";\r
23 \r
24 const Appoptions    opt_version     = 1;\r
25 const Appoptions    opt_help        = 1 << 1;\r
26 const Appoptions    opt_verbose     = 1 << 2;\r
27 const Appoptions    opt_output      = 1 << 3;\r
28 const Appoptions    opt_input       = 1 << 4;\r
29 \r
30 //----------------------------------------------------------------------------\r
31 //  Function prototypes\r
32 //----------------------------------------------------------------------------\r
33 inline bool isSet(const Appoptions &o1, const Appoptions &o2) {\r
34   return (o2 == (o1 & o2));\r
35 }\r
36 \r
37 Appoptions  checkOption(const char * inOptions);\r
38 void        compile(QCompilerCntl * const , QCalcUnits * const);\r
39 void        forceQuit(void);\r
40 void        printUsage(void);\r
41 void        printVersion(void);\r
42 void        errorAndQuit(const char * const inMessage);\r
43 std::string setOutputFilename(const std::string &inString);\r
44 \r
45 //----------------------------------------------------------------------------\r
46 /**\r
47  *  Main\r
48  */\r
49 int main(int argc, char **argv) {\r
50   Appoptions      parameters_ready    = 0;\r
51   QBits           *qBits              = NULL;\r
52   QCompilerCntl   *qCCntl             = NULL;\r
53   QCalcUnits      *qCalcUnits         = NULL;\r
54 \r
55   std::string               ofilename = "";\r
56   std::string               ifilename = "";\r
57   std::vector<std::string>  args;\r
58 \r
59   if (argc <= 1) {\r
60     printVersion();\r
61     printUsage();\r
62     std::exit(0);\r
63   }\r
64 \r
65   for (int i = 0; i < argc; i++) {\r
66     std::string tmpstr = argv[i];\r
67     args.push_back(tmpstr);\r
68   }\r
69 \r
70   int vec_size = args.size();\r
71   int arg_at   = 1;\r
72 \r
73   while (arg_at < vec_size) {\r
74     if ('-' == args[arg_at][0] && args[arg_at].length() > 1) {\r
75       Appoptions tmpoptions = checkOption(args[arg_at].c_str());\r
76 \r
77       //_____ HELP _____\r
78       if (isSet(tmpoptions, opt_help)) {\r
79         if (isSet(parameters_ready, opt_help)) {\r
80           errorAndQuit("-h option can be used only once.");\r
81         } else {\r
82           parameters_ready |= opt_help;\r
83         }\r
84       }\r
85 \r
86       //_____ VERBOSE _____\r
87       if (isSet(tmpoptions, opt_verbose)) {\r
88         if (isSet(parameters_ready, opt_verbose)) {\r
89           errorAndQuit("-v option can be used only once.");\r
90         } else {\r
91           parameters_ready |= opt_verbose;\r
92         }\r
93       }\r
94 \r
95       //_____ VERSION _____\r
96       if (isSet(tmpoptions, opt_version)) {\r
97         if (isSet(parameters_ready, opt_version)) {\r
98           errorAndQuit("-V option can be used only once.");\r
99         } else {\r
100           parameters_ready |= opt_version;\r
101         }\r
102       }\r
103 \r
104       //_____ OUTPUT _____\r
105       if (isSet(tmpoptions, opt_output)) {\r
106         if (isSet(parameters_ready, opt_output)) {\r
107           errorAndQuit("-o option can be used only once.");\r
108         }\r
109 \r
110         if (arg_at < vec_size - 1) {\r
111           ofilename         = args[++arg_at];\r
112           parameters_ready |= opt_output;\r
113         } else {\r
114           errorAndQuit("too few parameters.");\r
115         }\r
116       }\r
117       arg_at++;\r
118       continue;\r
119     }\r
120 \r
121     if (isSet(parameters_ready, opt_input)) {\r
122       errorAndQuit("too many input file.");\r
123     } else {\r
124       ifilename = args[arg_at];\r
125       parameters_ready |= opt_input;\r
126     }\r
127     arg_at++;\r
128   }\r
129 \r
130   //_____ VERSION _____\r
131   if (isSet(parameters_ready, opt_version)) printVersion();\r
132 \r
133   //_____ HELP ________\r
134   if (isSet(parameters_ready, opt_help))    printUsage();\r
135 \r
136   //_____ OUTPUT ______\r
137   if (isSet(parameters_ready, opt_input)) {\r
138     if (false == isSet(parameters_ready, opt_output)) {\r
139       ofilename = setOutputFilename(ifilename);\r
140     }\r
141 \r
142     std::ifstream ifs(ifilename.c_str(), std::ios::in);\r
143     if (!ifs) {\r
144       std::cerr << "Cannot open the input file.\n";\r
145       forceQuit();\r
146     }\r
147 \r
148     if (isSet(parameters_ready, opt_verbose)) {\r
149       std::cerr << "Input  file: " << ifilename << "\n"\r
150                 << "Output file: " << ofilename << "\n";\r
151     }\r
152 \r
153     try {\r
154       qCCntl      = new QCompilerCntl(ifs);\r
155       qCalcUnits  = new QCalcUnits(0);\r
156     } catch (const std::bad_alloc ex) {\r
157       std::cerr << "Failed in memory allocation.\n";\r
158       forceQuit();\r
159     }\r
160 \r
161     compile(qCCntl, qCalcUnits);\r
162 \r
163     try {\r
164       qBits       = new QBits(qCCntl->GetNumberOfQBits());\r
165     } catch (const std::bad_alloc &ex) {\r
166       std::cerr << "Failed in memory allocation.\n"\r
167                 << "This .mcd code needs at least "\r
168                 << (1 << (qCCntl->GetNumberOfQBits() + 1 + 3))\r
169                 << " bytes to allocate the qubits.\n";\r
170       forceQuit();\r
171     }\r
172 \r
173     for (unsigned int i = 0; i < qCalcUnits->size(); i++) {\r
174       if (isSet(parameters_ready, opt_verbose)) {\r
175         std::cerr << std::setw(15) << std::left\r
176                   << (*qCalcUnits)[i]->GetName()\r
177                   << " ... ";\r
178       }\r
179       (*qCalcUnits)[i]->Calc(qBits);\r
180       if (isSet(parameters_ready, opt_verbose)) {\r
181         std::cerr << "OK\n";\r
182       }\r
183     }\r
184 \r
185     qBits->SaveToFile(ofilename.c_str());\r
186     delete qBits;\r
187     delete qCCntl;\r
188 \r
189     for (unsigned int i = 0; i < qCalcUnits->size(); i++) {\r
190       delete (*qCalcUnits)[i];\r
191     }\r
192     delete qCalcUnits;\r
193     ifs.close();\r
194 \r
195     if (isSet(parameters_ready, opt_verbose)) {\r
196       std::cerr << "done." << std::endl;\r
197     }\r
198   }\r
199 \r
200   return 0;\r
201 }\r
202 \r
203 //----------------------------------------------------------------------------\r
204 /**\r
205  *  Check options\r
206  */\r
207 Appoptions checkOption(const char * inOptions) {\r
208   Appoptions retVal = 0;\r
209   inOptions++;\r
210   while ('\0' != *inOptions) {\r
211     switch (*inOptions) {\r
212     case 'h':\r
213       retVal |= opt_help;\r
214       break;\r
215     case 'o':\r
216       retVal |= opt_output;\r
217       break;\r
218     case 'v':\r
219       retVal |= opt_verbose;\r
220       break;\r
221     case 'V':\r
222       retVal |= opt_version;\r
223       break;\r
224     default:\r
225       errorAndQuit("there are some invalid options.");\r
226       break;\r
227     }\r
228     inOptions++;\r
229   }\r
230   return retVal;\r
231 }\r
232 \r
233 //----------------------------------------------------------------------------\r
234 /**\r
235  *\r
236  */\r
237 void compile(QCompilerCntl * const ioCompiler, QCalcUnits * const ioUnits) {\r
238   QCalcUnit *cu = NULL;\r
239   ioUnits->clear();\r
240 \r
241   if (true == ioCompiler->Compile()) {\r
242     unsigned int cntl_size = ioCompiler->GetNumberOfControl();\r
243     for (unsigned int i = 0; i < cntl_size; i++) {\r
244       cu = ioCompiler->AllocateControl(i);\r
245       if (NULL != cu) ioUnits->push_back(cu);\r
246     }\r
247   } else {\r
248     errorAndQuit("Parse error occurred.\n");\r
249   }\r
250 }\r
251 \r
252 //----------------------------------------------------------------------------\r
253 /**\r
254  *  Force quit\r
255  */\r
256 void forceQuit(void) {\r
257   std::cerr << "Quit forced.\n";\r
258   std::exit(1);\r
259 }\r
260 \r
261 //----------------------------------------------------------------------------\r
262 /**\r
263  *  Print usages\r
264  */\r
265 void printUsage(void) {\r
266   std::cout << "Usage: " << app_name\r
267             << " [-hvV] [-o output_file] input_file.mcd\n\n"\r
268             << "    -h  show this help\n"\r
269             << "    -v  verbose mode\n"\r
270             << "    -V  show version\n\n"\r
271             << std::flush;\r
272 }\r
273 \r
274 //----------------------------------------------------------------------------\r
275 /**\r
276  *  Print version\r
277  */\r
278 void printVersion(void) {\r
279   std::cout << "\nCopyright (C) 2002-2003 QCAD project\n"\r
280             << app_name << " version " << app_version << "\n\n"\r
281             << std::flush;\r
282 }\r
283 \r
284 //----------------------------------------------------------------------------\r
285 /**\r
286  *  Show message and quit\r
287  */\r
288 void errorAndQuit(const char * const inMessage) {\r
289   std::cerr << "Error: " << inMessage << "\n\n";\r
290   printUsage();\r
291   forceQuit();\r
292 }\r
293 \r
294 //----------------------------------------------------------------------------\r
295 /**\r
296  *  Set output filename\r
297  */\r
298 std::string setOutputFilename(const std::string &inString) {\r
299   std::string retString = "";\r
300 \r
301   unsigned int posdot = inString.rfind(".", inString.length() - 1);\r
302 \r
303   if (posdot == std::string::npos) {\r
304     retString = inString;\r
305   } else {\r
306     retString.assign(inString, 0, posdot);\r
307   }\r
308 \r
309   retString += ".qdt";\r
310 \r
311   return retString;\r
312 }\r
313 \r