Qucs-core  0.0.19
ucs.cpp
Go to the documentation of this file.
00001 /*
00002  * ucs.cpp - main program implementation
00003  *
00004  * Copyright (C) 2003-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 <stdlib.h>
00031 #include <assert.h>
00032 #include <string.h>
00033 #include <time.h>
00034 #include <list>
00035 #include <iostream>
00036 #include <fstream>
00037 
00038 #include "logging.h"
00039 #include "precision.h"
00040 #include "component.h"
00041 #include "components.h"
00042 #include "net.h"
00043 #include "input.h"
00044 #include "dataset.h"
00045 #include "equation.h"
00046 #include "environment.h"
00047 #include "exceptionstack.h"
00048 #include "check_netlist.h"
00049 #include "module.h"
00050 
00051 #if HAVE_UNISTD_H
00052 #include <unistd.h>
00053 #endif
00054 
00055 using namespace qucs;
00056 
00058 int main (int argc, char ** argv) {
00059 
00060   char * infile = NULL;
00061   char * outfile = NULL;
00062   char * projPath = NULL;
00063   net * subnet;
00064   input * in;
00065   circuit * gnd;
00066   dataset * out;
00067   environment * root;
00068   int listing = 0;
00069   int ret = 0;
00070   int dynamicLoad = 0;
00071 
00072   std::list<std::string> vamodules;
00073 
00074   loginit ();
00075   ::srand (::time (NULL));
00076 
00077   // check program arguments
00078   for (int i = 1; i < argc; i++) {
00079     if (!strcmp (argv[i], "-v") || !strcmp (argv[i], "--version")) {
00080       fprintf (stdout,
00081 #ifdef GIT_REVISION
00082         "Qucsator " PACKAGE_VERSION " (" GIT_REVISION ") \n"
00083 #else
00084         "Qucsator " PACKAGE_VERSION "\n"
00085 #endif
00086         "Copyright (C) 2003-2009 "
00087         "Stefan Jahn <stefan@lkcc.org>\n"
00088         "Copyright (C) 2006 Helene Parruitte <parruit@enseirb.fr>\n"
00089         "Copyright (C) 2006 Bastien Roucaries <roucaries.bastien@gmail.com>\n"
00090         "\nThis is free software; see the source for copying "
00091         "conditions.  There is NO\n"
00092         "warranty; not even for MERCHANTABILITY or FITNESS FOR A "
00093         "PARTICULAR PURPOSE.\n");
00094       return 0;
00095     }
00096     if (!strcmp (argv[i], "-h") || !strcmp (argv[i], "--help")) {
00097       fprintf (stdout,
00098         "Usage: %s [OPTION]...\n\n"
00099         "  -h, --help     display this help and exit\n"
00100         "  -v, --version  display version information and exit\n"
00101         "  -i FILENAME    use file as input netlist (default stdin)\n"
00102         "  -o FILENAME    use file as output dataset (default stdout)\n"
00103         "  -b, --bar      enable textual progress bar\n"
00104         "  -g, --gui      special progress bar used by gui\n"
00105         "  -c, --check    check the input netlist and exit\n"
00106 #if DEBUG
00107     "  -l, --listing  emit C-code for available definitions\n"
00108 #endif
00109     "  -p, --path     project path (or location of dynamic modules)\n"
00110     "  -m, --module   list of dynamic loaded modules (base names separated by space)\n"
00111         "\nReport bugs to <" PACKAGE_BUGREPORT ">.\n", argv[0]);
00112       return 0;
00113     }
00114     else if (!strcmp (argv[i], "-i")) {
00115       infile = argv[++i];
00116     }
00117     else if (!strcmp (argv[i], "-o")) {
00118       outfile = argv[++i];
00119       file_status = stdout;
00120     }
00121     else if (!strcmp (argv[i], "-b") || !strcmp (argv[i], "--bar")) {
00122       progressbar_enable = 1;
00123     }
00124     else if (!strcmp (argv[i], "-g") || !strcmp (argv[i], "--gui")) {
00125       progressbar_gui = 1;
00126     }
00127     else if (!strcmp (argv[i], "-c") || !strcmp (argv[i], "--check")) {
00128       netlist_check = 1;
00129     }
00130     else if (!strcmp (argv[i], "-l") || !strcmp (argv[i], "--listing")) {
00131       listing = 1;
00132     }
00133     // \todo remove command arguments
00134     else if (!strcmp (argv[i], "-p") || !strcmp (argv[i], "--path")) {
00135       projPath = argv[++i];
00136     }
00137     else if (!strcmp (argv[i], "-m") || !strcmp (argv[i], "--module")) {
00138       dynamicLoad = 1;
00139     }
00140     else {
00141       if (dynamicLoad) {
00142         vamodules.push_back(argv[i]);
00143       }
00144     }
00145   }
00146 
00147   // create static modules
00148   module::registerModules ();
00149 
00150 #if DEBUG
00151   // emit C-code for available definitions if requested and exit
00152   if (listing) {
00153     module::print ();
00154     return ret;
00155   }
00156 #endif /* DEBUG */
00157 
00158   // look for dynamic libs, load and register them
00159   // \todo, keep this way of loading or keep only annotated netlist?
00160   if (dynamicLoad) {
00161     module::registerDynamicModules (projPath, vamodules);
00162   }
00163 
00164   else { //no argument, look into netlist
00165 
00166     std::string sLine = "";
00167     std::ifstream file;
00168 
00169     std::string projPathNet ="";
00170     std::string projVaMoules = "";
00171 
00172     file.open(infile);
00173 
00174     while (!file.eof()) {
00175         getline(file, sLine);
00176 
00177         if (sLine.find("--path") != std::string::npos) {
00178             std::cout << sLine << std::endl;
00179 
00180             size_t pos = 0;
00181             pos = sLine.find("=");
00182             sLine.erase(0, pos + 1);
00183             std::cout << sLine << std::endl;
00184 
00185 //            projPath =  const_cast<char*>(sLine.c_str());
00186 //            projPath = (char*)sLine.c_str();
00187 
00188 //            std::cout << "inside" << projPath << std::endl;
00189 
00190             projPathNet = sLine;
00191 
00192         }
00193 
00194         if (sLine.find("--module") != std::string::npos) {
00195             std::cout << sLine << std::endl;
00196 
00197             size_t pos = 0;
00198             pos = sLine.find("=");
00199             sLine.erase(0, pos + 1);
00200             //std::cout << sLine << std::endl;
00201             projVaMoules = sLine;
00202 
00203             // put module names into list
00204             std::istringstream ss(sLine);
00205             std::string token;
00206 
00207             while(std::getline(ss, token, ' ')) {
00208                 std::cout << token << '\n';
00209 
00210                 vamodules.push_back(token);
00211             }
00212         }
00213     }
00214 
00215     module::registerDynamicModules ((char*)projPathNet.c_str(), vamodules);
00216     file.close();
00217   }
00218 
00219 
00220   // create root environment
00221   root = new environment (std::string("root"));
00222 
00223   // create netlist object and input
00224   subnet = new net ("subnet");
00225   in = infile ? new input (infile) : new input ();
00226 
00227   // pass root environment to netlist object and input
00228   subnet->setEnv (root);
00229   in->setEnv (root);
00230 
00231   // get input netlist
00232   if (in->netlist (subnet) != 0) {
00233     if (netlist_check) {
00234       logprint (LOG_STATUS, "checker notice, netlist check FAILED\n");
00235     }
00236     return -1;
00237   }
00238   if (netlist_check) {
00239     logprint (LOG_STATUS, "checker notice, netlist OK\n");
00240     return 0;
00241   }
00242 
00243   // attach a ground to the netlist
00244   gnd = new ground ();
00245   gnd->setNode (0, "gnd");
00246   gnd->setName ("GND");
00247   subnet->insertCircuit (gnd);
00248 
00249   // analyse the netlist
00250   int err = 0;
00251   out = subnet->runAnalysis (err);
00252   ret |= err;
00253 
00254   // evaluate output dataset
00255   ret |= root->equationSolver (out);
00256   out->setFile (outfile);
00257   out->print ();
00258 
00259   estack.print ("uncaught");
00260 
00261   delete subnet;
00262   delete in;
00263   delete out;
00264   delete root;
00265 
00266   // delete static modules and dynamic modules
00267   module::unregisterModules ();
00268 
00269   // close all the dynamic libs if any opened
00270   module::closeDynamicLibs();
00271 
00272   netlist_destroy_env ();
00273   return ret;
00274 }