OSDN Git Service

2dda0ecb957437397642b10cd04bd7d29f1334aa
[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 getBaseFilename(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       ofilename = getBaseFilename(ifilename)+".qdt";\r
141     }\r
142 \r
143     std::ifstream ifs(ifilename.c_str(), std::ios::in);\r
144     if (!ifs) {\r
145       std::cerr << "Cannot open the input file.\n";\r
146       forceQuit();\r
147     }\r
148 \r
149     if (isSet(parameters_ready, opt_verbose)) {\r
150       std::cerr << "Input  file: " << ifilename << "\n"\r
151                 << "Output file: " << ofilename << "\n";\r
152     }\r
153 \r
154     try {\r
155       qCCntl      = new QCompilerCntl(ifs);\r
156       qCalcUnits  = new QCalcUnits(0);\r
157     } catch (const std::bad_alloc ex) {\r
158       std::cerr << "Failed in memory allocation.\n";\r
159       forceQuit();\r
160     }\r
161 \r
162     compile(qCCntl, qCalcUnits);\r
163 \r
164     try {\r
165       qBits       = new QBits(qCCntl->GetNumberOfQBits());\r
166     } catch (const std::bad_alloc &ex) {\r
167       std::cerr << "Failed in memory allocation.\n"\r
168                 << "This .mcd code needs at least "\r
169                 << (1 << (qCCntl->GetNumberOfQBits() + 1 + 3))\r
170                 << " bytes to allocate the qubits.\n";\r
171       forceQuit();\r
172     }\r
173 \r
174     for (unsigned int i = 0; i < qCalcUnits->size(); i++) {\r
175       if (isSet(parameters_ready, opt_verbose)) {\r
176         std::cerr << std::setw(15) << std::left\r
177                   << (*qCalcUnits)[i]->GetName()\r
178                   << " ... ";\r
179       }\r
180       (*qCalcUnits)[i]->Calc(qBits);\r
181       if (isSet(parameters_ready, opt_verbose)) {\r
182         std::cerr << "OK\n";\r
183       }\r
184     }\r
185 \r
186     qBits->SaveToFile(ofilename.c_str());\r
187     qBits->SaveAsText("test.txt");\r
188     delete qBits;\r
189     delete qCCntl;\r
190 \r
191     for (unsigned int i = 0; i < qCalcUnits->size(); i++) {\r
192       delete (*qCalcUnits)[i];\r
193     }\r
194     delete qCalcUnits;\r
195     ifs.close();\r
196 \r
197     if (isSet(parameters_ready, opt_verbose)) {\r
198       std::cerr << "done." << std::endl;\r
199     }\r
200   }\r
201 \r
202   return 0;\r
203 }\r
204 \r
205 //----------------------------------------------------------------------------\r
206 /**\r
207  *  Check options\r
208  */\r
209 Appoptions checkOption(const char * inOptions) {\r
210   Appoptions retVal = 0;\r
211   inOptions++;\r
212   while ('\0' != *inOptions) {\r
213     switch (*inOptions) {\r
214     case 'h':\r
215       retVal |= opt_help;\r
216       break;\r
217     case 'o':\r
218       retVal |= opt_output;\r
219       break;\r
220     case 'v':\r
221       retVal |= opt_verbose;\r
222       break;\r
223     case 'V':\r
224       retVal |= opt_version;\r
225       break;\r
226     default:\r
227       errorAndQuit("there are some invalid options.");\r
228       break;\r
229     }\r
230     inOptions++;\r
231   }\r
232   return retVal;\r
233 }\r
234 \r
235 //----------------------------------------------------------------------------\r
236 /**\r
237  *\r
238  */\r
239 void compile(QCompilerCntl * const ioCompiler, QCalcUnits * const ioUnits) {\r
240   QCalcUnit *cu = NULL;\r
241   ioUnits->clear();\r
242 \r
243   if (true == ioCompiler->Compile()) {\r
244     unsigned int cntl_size = ioCompiler->GetNumberOfControl();\r
245     for (unsigned int i = 0; i < cntl_size; i++) {\r
246       cu = ioCompiler->AllocateControl(i);\r
247       if (NULL != cu) ioUnits->push_back(cu);\r
248     }\r
249   } else {\r
250     errorAndQuit("Parse error occurred.\n");\r
251   }\r
252 }\r
253 \r
254 //----------------------------------------------------------------------------\r
255 /**\r
256  *  Force quit\r
257  */\r
258 void forceQuit(void) {\r
259   std::cerr << "Quit forced.\n";\r
260   std::exit(1);\r
261 }\r
262 \r
263 //----------------------------------------------------------------------------\r
264 /**\r
265  *  Print usages\r
266  */\r
267 void printUsage(void) {\r
268   std::cout << "Usage: " << app_name\r
269             << " [-hvV] [-o output_file] input_file.mcd\n\n"\r
270             << "    -h  show this help\n"\r
271             << "    -v  verbose mode\n"\r
272             << "    -V  show version\n\n"\r
273             << std::flush;\r
274 }\r
275 \r
276 //----------------------------------------------------------------------------\r
277 /**\r
278  *  Print version\r
279  */\r
280 void printVersion(void) {\r
281   std::cout << "\nCopyright (C) 2002-2003 QCAD project\n"\r
282             << app_name << " version " << app_version << "\n\n"\r
283             << std::flush;\r
284 }\r
285 \r
286 //----------------------------------------------------------------------------\r
287 /**\r
288  *  Show message and quit\r
289  */\r
290 void errorAndQuit(const char * const inMessage) {\r
291   std::cerr << "Error: " << inMessage << "\n\n";\r
292   printUsage();\r
293   forceQuit();\r
294 }\r
295 \r
296 //----------------------------------------------------------------------------\r
297 /**\r
298  *  get basename of filename\r
299  */\r
300 std::string getBaseFilename(const std::string &inString) {\r
301   std::string retString = "";\r
302 \r
303   unsigned int posdot = inString.rfind(".", inString.length() - 1);\r
304 \r
305   if (posdot == std::string::npos) {\r
306     retString = inString;\r
307   } else {\r
308     retString.assign(inString, 0, posdot);\r
309   }\r
310   return retString;\r
311 }\r
312 //----------------------------------------------------------------------------\r