Qucs-core  0.0.19
qucsconv.cpp
Go to the documentation of this file.
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