Qucs-core
0.0.19
|
00001 /* 00002 * qucsconv.cpp - main converter program implementation 00003 * 00004 * Copyright (C) 2004, 2005, 2006, 2007, 2009 Stefan Jahn <stefan@lkcc.org> 00005 * 00006 * This is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2, or (at your option) 00009 * any later version. 00010 * 00011 * This software is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this package; see the file COPYING. If not, write to 00018 * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 00019 * Boston, MA 02110-1301, USA. 00020 * 00021 * $Id$ 00022 * 00023 */ 00024 00025 #if HAVE_CONFIG_H 00026 # include <config.h> 00027 #endif 00028 00029 #include <stdio.h> 00030 #include <assert.h> 00031 #include <string.h> 00032 #include <errno.h> 00033 00034 #include "logging.h" 00035 #include "precision.h" 00036 #include "check_spice.h" 00037 #include "check_vcd.h" 00038 #include "check_citi.h" 00039 #include "check_touchstone.h" 00040 #include "check_csv.h" 00041 #include "check_zvr.h" 00042 #include "check_mdl.h" 00043 #include "check_dataset.h" 00044 #include "qucs_producer.h" 00045 #include "csv_producer.h" 00046 #include "touchstone_producer.h" 00047 #include "matlab_producer.h" 00048 #include "dataset.h" 00049 00050 using namespace qucs; 00051 00052 /* structure defining a conversion */ 00053 struct actionset_t { 00054 const char * in; /* -if parameter */ 00055 const char * out; /* -of parameter */ 00056 00057 /* callback for the logic, return error code of application */ 00058 int (* execute) (struct actionset_t *, char * infile, char * outfile); 00059 }; 00060 00061 /* data variable specification */ 00062 char * data_var = NULL; 00063 00064 /* required forward declarations */ 00065 int spice2qucs (struct actionset_t *, char *, char *); 00066 int vcd2qucs (struct actionset_t *, char *, char *); 00067 int qucs2csv (struct actionset_t *, char *, char *); 00068 int qucs2touch (struct actionset_t *, char *, char *); 00069 int citi2qucs (struct actionset_t *, char *, char *); 00070 int touch2qucs (struct actionset_t *, char *, char *); 00071 int csv2qucs (struct actionset_t *, char *, char *); 00072 int zvr2qucs (struct actionset_t *, char *, char *); 00073 int mdl2qucs (struct actionset_t *, char *, char *); 00074 int qucs2mat (struct actionset_t *, char *, char *); 00075 00076 /* conversion definitions */ 00077 struct actionset_t actionset[] = { 00078 { "spice", "qucs", spice2qucs }, 00079 { "spice", "qucslib", spice2qucs }, 00080 { "vcd", "qucsdata", vcd2qucs }, 00081 { "qucsdata", "csv", qucs2csv }, 00082 { "qucsdata", "touchstone", qucs2touch }, 00083 { "citi", "qucsdata", citi2qucs }, 00084 { "touchstone", "qucsdata", touch2qucs }, 00085 { "csv", "qucsdata", csv2qucs }, 00086 { "zvr", "qucsdata", zvr2qucs }, 00087 { "mdl", "qucsdata", mdl2qucs }, 00088 { "qucsdata", "matlab", qucs2mat }, 00089 { NULL, NULL, NULL} 00090 }; 00091 00092 /* opens the given file, fallback to stdin/stdout */ 00093 FILE * open_file (char * file, const char * flag) { 00094 FILE * fd = NULL; 00095 if (file) { 00096 if ((fd = fopen (file, flag)) == NULL) { 00097 fprintf (stderr, "cannot open file `%s': %s, using %s instead\n", 00098 file, strerror (errno), flag[0] == 'r' ? "stdin" : "stdout"); 00099 fd = flag[0] == 'r' ? stdin : stdout; 00100 } 00101 } 00102 else { 00103 fd = flag[0] == 'r' ? stdin : stdout; 00104 } 00105 return fd; 00106 } 00107 00108 /* main entry point */ 00109 int main (int argc, char ** argv) { 00110 00111 char * infile = NULL, * outfile = NULL, * input = NULL, * output = NULL; 00112 00113 loginit (); 00114 00115 // check program arguments 00116 for (int i = 1; i < argc; i++) { 00117 if (!strcmp (argv[i], "-v") || !strcmp (argv[i], "--version")) { 00118 fprintf (stdout, 00119 #ifdef GIT_REVISION 00120 "QucsConverter " PACKAGE_VERSION " (" GIT_REVISION ") \n" 00121 #else 00122 "QucsConverter " PACKAGE_VERSION "\n" 00123 #endif 00124 00125 "Copyright (C) 2004, 2005, 2006, 2007 Stefan Jahn <stefan@lkcc.org>\n" 00126 "\nThis is free software; see the source for copying " 00127 "conditions. There is NO\n" 00128 "warranty; not even for MERCHANTABILITY or FITNESS FOR A " 00129 "PARTICULAR PURPOSE.\n"); 00130 return 0; 00131 } 00132 if (!strcmp (argv[i], "-h") || !strcmp (argv[i], "--help")) { 00133 fprintf (stdout, 00134 "Usage: %s [OPTION]...\n\n" 00135 " -h, --help display this help and exit\n" 00136 " -v, --version display version information and exit\n" 00137 " -i FILENAME use file as input file (default stdin)\n" 00138 " -o FILENAME use file as output file (default stdout)\n" 00139 " -if FORMAT input data specification (see FORMAT below)\n" 00140 " -of FORMAT output data specification (see FORMAT below)\n" 00141 " -a, --noaction do not include netlist actions in the output\n" 00142 " -g GNDNODE replace ground node\n" 00143 " -d DATANAME data variable specification\n" 00144 " -c, --correct enable node correction\n" 00145 "\nFORMAT: The input - output format pair should be one of the following:\n" 00146 " inputformat - outputformat\n" 00147 " spice - qucs\n" 00148 " spice - qucslib\n" 00149 " vcd - qucsdata\n" 00150 " qucsdata - csv\n" 00151 " qucsdata - touchstone\n" 00152 " citi - qucsdata\n" 00153 " touchstone - qucsdata\n" 00154 " csv - qucsdata\n" 00155 " zvr - qucsdata\n" 00156 " mdl - qucsdata\n" 00157 " qucsdata - matlab\n" 00158 "\nReport bugs to <" PACKAGE_BUGREPORT ">.\n", argv[0]); 00159 return 0; 00160 } 00161 else if (!strcmp (argv[i], "-i")) { 00162 infile = argv[++i]; 00163 } 00164 else if (!strcmp (argv[i], "-o")) { 00165 outfile = argv[++i]; 00166 } 00167 else if (!strcmp (argv[i], "-if")) { 00168 input = argv[++i]; 00169 } 00170 else if (!strcmp (argv[i], "-of")) { 00171 output = argv[++i]; 00172 } 00173 else if (!strcmp (argv[i], "-a") || !strcmp (argv[i], "--noaction")) { 00174 qucs_actions = 0; 00175 } 00176 else if (!strcmp (argv[i], "-g")) { 00177 if (argv[++i]) qucs_gnd = argv[i]; 00178 } 00179 else if (!strcmp (argv[i], "-d")) { 00180 if (argv[++i]) data_var = argv[i]; 00181 } 00182 else if (!strcmp (argv[i], "-c") || !strcmp (argv[i], "--correct")) { 00183 vcd_correct = 1; 00184 } 00185 } 00186 00187 // check input/output formats 00188 int infound = 0; 00189 int outfound = 0; 00190 for (int j = 0; actionset[j].in != NULL; j++) { 00191 int in = 0, out = 0; 00192 if (input && !strcmp (input, actionset[j].in)) { 00193 in = infound = 1; 00194 } 00195 if (output && !strcmp (output, actionset[j].out)) { 00196 out = outfound = 1; 00197 } 00198 if (in && out) { 00199 return actionset[j].execute (&actionset[j], infile, outfile); 00200 } 00201 } 00202 00203 // no appropriate conversion found 00204 if (!infound) { 00205 fprintf (stderr, "invalid input data specification `%s'\n", 00206 input ? input : "not given"); 00207 } 00208 if (!outfound) { 00209 fprintf (stderr, "invalid output data specification `%s'\n", 00210 output ? output : "not given"); 00211 } 00212 fprintf (stderr, "invalid input/output data specification `%s->%s'\n", 00213 input ? input : "not given", output ? output : "not given"); 00214 return -1; 00215 } 00216 00217 // SPICE to Qucs conversion. 00218 int spice2qucs (struct actionset_t * action, char * infile, char * outfile) { 00219 int ret = 0; 00220 if ((spice_in = open_file (infile, "r")) == NULL) { 00221 ret = -1; 00222 } else if (spice_parse () != 0) { 00223 ret = -1; 00224 } else if (spice_checker () != 0) { 00225 ret = -1; 00226 } 00227 spice_lex_destroy (); 00228 if (spice_in) 00229 fclose (spice_in); 00230 if (ret) { 00231 spice_destroy (); 00232 return -1; 00233 } 00234 00235 if ((qucs_out = open_file (outfile, "w")) == NULL) 00236 return -1; 00237 if (!strcmp (action->out, "qucs")) 00238 qucs_producer (); 00239 else /* "qucslib" */ 00240 qucslib_producer (); 00241 fclose (qucs_out); 00242 spice_destroy (); 00243 return 0; 00244 } 00245 00246 // VCD to Qucs conversion. 00247 int vcd2qucs (struct actionset_t * action, char * infile, char * outfile) { 00248 int ret = 0; 00249 vcd_init (); 00250 if ((vcd_in = open_file (infile, "r")) == NULL) { 00251 ret = -1; 00252 } else if (vcd_parse () != 0) { 00253 ret = -1; 00254 } else if (vcd_checker () != 0) { 00255 ret = -1; 00256 } 00257 vcd_lex_destroy (); 00258 if (vcd_in) 00259 fclose (vcd_in); 00260 if (ret) { 00261 vcd_destroy (); 00262 return -1; 00263 } 00264 00265 if ((qucs_out = open_file (outfile, "w")) == NULL) 00266 return -1; 00267 if (!strcmp (action->out, "qucsdata")) 00268 qucsdata_producer_vcd (); 00269 fclose (qucs_out); 00270 vcd_destroy (); 00271 return 0; 00272 } 00273 00274 // Qucs dataset to CSV conversion. 00275 int qucs2csv (struct actionset_t * action, char * infile, char * outfile) { 00276 int ret = 0; 00277 if ((dataset_in = open_file (infile, "r")) == NULL) { 00278 ret = -1; 00279 } else if (dataset_parse () != 0) { 00280 ret = -1; 00281 } else if (dataset_result == NULL) { 00282 ret = -1; 00283 } else if (dataset_check (dataset_result) != 0) { 00284 delete dataset_result; 00285 dataset_result = NULL; 00286 ret = -1; 00287 } 00288 qucs_data = dataset_result; 00289 dataset_result = NULL; 00290 dataset_lex_destroy (); 00291 if (dataset_in) 00292 fclose (dataset_in); 00293 if (ret) 00294 return -1; 00295 00296 if ((csv_out = open_file (outfile, "w")) == NULL) 00297 return -1; 00298 if (!strcmp (action->out, "csv")) { 00299 if (data_var != NULL) 00300 csv_producer (data_var, ";"); 00301 else { 00302 fprintf (stderr, "no data variable given (passed by -d option)\n"); 00303 ret = -1; 00304 } 00305 fclose (csv_out); 00306 return ret; 00307 } 00308 return -1; 00309 } 00310 00311 // Qucs dataset to Touchstone conversion. 00312 int qucs2touch (struct actionset_t * action, char * infile, char * outfile) { 00313 int ret = 0; 00314 if ((dataset_in = open_file (infile, "r")) == NULL) { 00315 ret = -1; 00316 } else if (dataset_parse () != 0) { 00317 ret = -1; 00318 } else if (dataset_result == NULL) { 00319 ret = -1; 00320 } else if (dataset_check (dataset_result) != 0) { 00321 delete dataset_result; 00322 dataset_result = NULL; 00323 ret = -1; 00324 } 00325 qucs_data = dataset_result; 00326 dataset_result = NULL; 00327 dataset_lex_destroy (); 00328 if (dataset_in) 00329 fclose (dataset_in); 00330 if (ret) 00331 return -1; 00332 00333 if ((touchstone_out = open_file (outfile, "w")) == NULL) 00334 return -1; 00335 if (!strcmp (action->out, "touchstone")) { 00336 touchstone_producer (data_var); 00337 fclose (touchstone_out); 00338 return ret; 00339 } 00340 return -1; 00341 } 00342 00343 // Qucs dataset to Matlab conversion. 00344 int qucs2mat (struct actionset_t * action, char * infile, char * outfile) { 00345 int ret = 0; 00346 if ((dataset_in = open_file (infile, "r")) == NULL) { 00347 ret = -1; 00348 } else if (dataset_parse () != 0) { 00349 ret = -1; 00350 } else if (dataset_result == NULL) { 00351 ret = -1; 00352 } else if (dataset_check (dataset_result) != 0) { 00353 delete dataset_result; 00354 dataset_result = NULL; 00355 ret = -1; 00356 } 00357 qucs_data = dataset_result; 00358 dataset_result = NULL; 00359 dataset_lex_destroy (); 00360 if (dataset_in) 00361 fclose (dataset_in); 00362 if (ret) 00363 return -1; 00364 00365 if ((matlab_out = open_file (outfile, "wb")) == NULL) 00366 return -1; 00367 if (!strcmp (action->out, "matlab")) { 00368 matlab_producer (); 00369 fclose (matlab_out); 00370 return ret; 00371 } 00372 return -1; 00373 } 00374 00375 // CITIfile to Qucs conversion. 00376 int citi2qucs (struct actionset_t * action, char * infile, char * outfile) { 00377 int ret = 0; 00378 citi_init (); 00379 if ((citi_in = open_file (infile, "r")) == NULL) { 00380 ret = -1; 00381 } else if (citi_parse () != 0) { 00382 ret = -1; 00383 } else if (citi_check () != 0) { 00384 ret = -1; 00385 } 00386 citi_lex_destroy (); 00387 if (citi_in) 00388 fclose (citi_in); 00389 if (ret) { 00390 citi_destroy (); 00391 return -1; 00392 } 00393 00394 if (!strcmp (action->out, "qucsdata")) { 00395 citi_result->setFile (outfile); 00396 qucsdata_producer (citi_result); 00397 } 00398 citi_destroy (); 00399 return 0; 00400 } 00401 00402 // Touchstone to Qucs conversion. 00403 int touch2qucs (struct actionset_t * action, char * infile, char * outfile) { 00404 int ret = 0; 00405 touchstone_init (); 00406 if ((touchstone_in = open_file (infile, "r")) == NULL) { 00407 ret = -1; 00408 } else if (touchstone_parse () != 0) { 00409 ret = -1; 00410 } else if (touchstone_check () != 0) { 00411 ret = -1; 00412 } 00413 touchstone_lex_destroy (); 00414 if (touchstone_in) 00415 fclose (touchstone_in); 00416 if (ret) { 00417 touchstone_destroy (); 00418 return -1; 00419 } 00420 00421 if (!strcmp (action->out, "qucsdata")) { 00422 touchstone_result->setFile (outfile); 00423 qucsdata_producer (touchstone_result); 00424 } 00425 touchstone_destroy (); 00426 return 0; 00427 } 00428 00429 // CSV to Qucs conversion. 00430 int csv2qucs (struct actionset_t * action, char * infile, char * outfile) { 00431 int ret = 0; 00432 csv_init (); 00433 if ((csv_in = open_file (infile, "r")) == NULL) { 00434 ret = -1; 00435 } else if (csv_parse () != 0) { 00436 ret = -1; 00437 } else if (csv_check () != 0) { 00438 ret = -1; 00439 } 00440 csv_lex_destroy (); 00441 if (csv_in) 00442 fclose (csv_in); 00443 if (ret) { 00444 csv_destroy (); 00445 return -1; 00446 } 00447 00448 if (!strcmp (action->out, "qucsdata")) { 00449 csv_result->setFile (outfile); 00450 qucsdata_producer (csv_result); 00451 } 00452 csv_destroy (); 00453 return 0; 00454 } 00455 00456 // ZVR to Qucs conversion. 00457 int zvr2qucs (struct actionset_t * action, char * infile, char * outfile) { 00458 int ret = 0; 00459 zvr_init (); 00460 if ((zvr_in = open_file (infile, "r")) == NULL) { 00461 ret = -1; 00462 } else if (zvr_parse () != 0) { 00463 ret = -1; 00464 } else if (zvr_check () != 0) { 00465 ret = -1; 00466 } 00467 zvr_lex_destroy (); 00468 if (zvr_in) 00469 fclose (zvr_in); 00470 if (ret) { 00471 zvr_destroy (); 00472 return -1; 00473 } 00474 if (!strcmp (action->out, "qucsdata")) { 00475 zvr_result->setFile (outfile); 00476 qucsdata_producer (zvr_result); 00477 } 00478 zvr_destroy (); 00479 return 0; 00480 } 00481 00482 // MDL to Qucs conversion. 00483 int mdl2qucs (struct actionset_t * action, char * infile, char * outfile) { 00484 int ret = 0; 00485 mdl_init (); 00486 if ((mdl_in = open_file (infile, "r")) == NULL) { 00487 ret = -1; 00488 } else if (mdl_parse () != 0) { 00489 ret = -1; 00490 } else if (mdl_check () != 0) { 00491 ret = -1; 00492 } 00493 mdl_lex_destroy (); 00494 if (mdl_in) 00495 fclose (mdl_in); 00496 if (ret) { 00497 mdl_destroy (); 00498 return -1; 00499 } 00500 if (!strcmp (action->out, "qucsdata")) { 00501 mdl_result->setFile (outfile); 00502 qucsdata_producer (mdl_result); 00503 } 00504 mdl_destroy (); 00505 return 0; 00506 } 00507