Qucs-core
0.0.19
|
00001 /* 00002 * module.cpp - module class implementation 00003 * 00004 * Copyright (C) 2008, 2009, 2010 Stefan Jahn <stefan@lkcc.org> 00005 * New models added Mike Brinson 2013 mbrin72043@yahoo.co.uk 00006 * 00007 * This is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2, or (at your option) 00010 * any later version. 00011 * 00012 * This software is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this package; see the file COPYING. If not, write to 00019 * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 00020 * Boston, MA 02110-1301, USA. 00021 * 00022 * $Id: module.cpp 1872 2013-03-06 14:13:37Z fransschreuder $ 00023 * 00024 */ 00025 00026 #if HAVE_CONFIG_H 00027 # include <config.h> 00028 #endif 00029 00030 #include <iostream> 00031 #include <stdio.h> 00032 #include <stdlib.h> 00033 #include <map> 00034 #include <list> 00035 00036 #include "netdefs.h" 00037 #include "components.h" 00038 #include "analyses.h" 00039 #include "netdefs.h" 00040 #include "module.h" 00041 00042 #ifdef __MINGW32__ 00043 #include <windows.h> 00044 #else 00045 #include <dlfcn.h> 00046 #endif 00047 00048 #include <cstdlib> //for exit 00049 00050 // Global module hash. 00051 qucs::hash<module> module::modules; 00052 00053 // Our global factories for making loaded circuit objects 00054 // The factories are populated as dynamic modules are loaded 00055 // factorycreate hold the loaded modules constructor function 00056 std::map< std::string, creator_t *, std::less<std::string> > factorycreate; 00057 // factorydef hold the loaded modules definitions 00058 std::map< std::string, defs_t *, std::less<std::string> > factorydef; 00059 00060 #if __MINGW32__ 00061 std::list<HINSTANCE> dl_list; // list to hold handles for dynamic libs 00062 std::list<HINSTANCE>::iterator itr; 00063 #else 00064 std::list<void *> dl_list; // list to hold handles for dynamic libs 00065 std::list<void *>::iterator itr; 00066 #endif 00067 00068 // Constructor creates an instance of the module class. 00069 module::module () { 00070 definition = NULL; 00071 circreate = NULL; 00072 anacreate = NULL; 00073 } 00074 00075 // Destructor deletes an instance of the module class. 00076 module::~module () { 00077 } 00078 00079 // Definitions which do not fit elsewhere. 00080 static struct property_t props1[] = { 00081 PROP_NO_PROP }; 00082 static struct property_t props2[] = { 00083 { "Type", PROP_STR, { PROP_NO_VAL, "DEF1" }, PROP_NO_RANGE }, 00084 PROP_NO_PROP }; 00085 00086 struct define_t miscdef1 = 00087 { "Def", PROP_NODES, PROP_ACTION, PROP_NO_SUBSTRATE, PROP_LINEAR, 00088 props1, props1 }; 00089 00090 struct define_t miscdef2 = 00091 { "Sub", PROP_NODES, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, 00092 props1, props2 }; 00093 00094 // Registers an analysis object to the list of available modules. 00095 void module::registerModule (analysis_definer_t define, 00096 analysis_creator_t create) { 00097 module * m = new module (); 00098 m->definition = define (); 00099 m->anacreate = create; 00100 modules.put ((char *) define()->type, m); 00101 } 00102 00103 // Registers a circuit object to the list of available modules. 00104 void module::registerModule (circuit_definer_t define, 00105 circuit_creator_t create) { 00106 module * m = new module (); 00107 m->definition = define (); 00108 m->circreate = create; 00109 registerModule (define()->type, m); 00110 } 00111 00112 // Registers a miscellaneous object to the list of available modules. 00113 void module::registerModule (misc_definer_t define) { 00114 module * m = new module (); 00115 m->definition = define (); 00116 registerModule (define()->type, m); 00117 } 00118 00119 /* Registers a miscellaneous structure just defined by a somple 00120 define_t structure to the list of available modules. */ 00121 void module::registerModule (struct define_t * define) { 00122 module * m = new module (); 00123 m->definition = define; 00124 registerModule (define->type, m); 00125 } 00126 00127 // Puts a module into the available module hash. 00128 void module::registerModule (const char * type, module * m) { 00129 if (modules.get ((char *) type) != NULL) { 00130 logprint (LOG_ERROR, "module already registered: %s\n", type); 00131 } 00132 else { 00133 modules.put ((char *) type, m); 00134 } 00135 } 00136 00137 /* Returns the definition of a module specified by its type name if 00138 such is existing and otherwise NULL. */ 00139 struct define_t * module::getModule (char * type) { 00140 module * m = modules.get (type); 00141 if (m != NULL) { 00142 return m->definition; 00143 } 00144 return NULL; 00145 } 00146 00147 // Helper macros. 00148 #define REGISTER_CIRCUIT(val) \ 00149 registerModule (&val::definition, &val::create) 00150 #define REGISTER_ANALYSIS(val) \ 00151 registerModule (&val::definition, &val::create) 00152 #define REGISTER_MISC(val) \ 00153 registerModule (&val::definition) 00154 00155 // Global static module registration. 00156 void module::registerModules (void) { 00157 00158 // miscellaneous 00159 registerModule (&miscdef1); 00160 registerModule (&miscdef2); 00161 REGISTER_MISC (nodeset); 00162 REGISTER_MISC (substrate); 00163 00164 // circuit components 00165 REGISTER_CIRCUIT (resistor); 00166 REGISTER_CIRCUIT (capacitor); 00167 REGISTER_CIRCUIT (pac); 00168 REGISTER_CIRCUIT (inductor); 00169 REGISTER_CIRCUIT (vccs); 00170 REGISTER_CIRCUIT (cccs); 00171 REGISTER_CIRCUIT (vcvs); 00172 REGISTER_CIRCUIT (ccvs); 00173 REGISTER_CIRCUIT (biastee); 00174 REGISTER_CIRCUIT (dcfeed); 00175 REGISTER_CIRCUIT (dcblock); 00176 REGISTER_CIRCUIT (circulator); 00177 REGISTER_CIRCUIT (attenuator); 00178 REGISTER_CIRCUIT (isolator); 00179 REGISTER_CIRCUIT (trafo); 00180 REGISTER_CIRCUIT (strafo); 00181 REGISTER_CIRCUIT (vdc); 00182 REGISTER_CIRCUIT (idc); 00183 REGISTER_CIRCUIT (vac); 00184 REGISTER_CIRCUIT (iac); 00185 REGISTER_CIRCUIT (iexp); 00186 REGISTER_CIRCUIT (vexp); 00187 REGISTER_CIRCUIT (ifile); 00188 REGISTER_CIRCUIT (vfile); 00189 REGISTER_CIRCUIT (vam); 00190 REGISTER_CIRCUIT (vpm); 00191 REGISTER_CIRCUIT (vpulse); 00192 REGISTER_CIRCUIT (ipulse); 00193 REGISTER_CIRCUIT (vrect); 00194 REGISTER_CIRCUIT (irect); 00195 REGISTER_CIRCUIT (gyrator); 00196 REGISTER_CIRCUIT (phaseshifter); 00197 REGISTER_CIRCUIT (tswitch); 00198 REGISTER_CIRCUIT (relais); 00199 REGISTER_CIRCUIT (tline); 00200 REGISTER_CIRCUIT (tline4p); 00201 REGISTER_CIRCUIT (ctline); 00202 REGISTER_CIRCUIT (coaxline); 00203 REGISTER_CIRCUIT (rectline); 00204 REGISTER_CIRCUIT (twistedpair); 00205 REGISTER_CIRCUIT (rlcg); 00206 REGISTER_CIRCUIT (coupler); 00207 REGISTER_CIRCUIT (hybrid); 00208 REGISTER_CIRCUIT (diode); 00209 REGISTER_CIRCUIT (eqndefined); 00210 REGISTER_CIRCUIT (rfedd); 00211 REGISTER_CIRCUIT (diac); 00212 REGISTER_CIRCUIT (thyristor); 00213 REGISTER_CIRCUIT (triac); 00214 REGISTER_CIRCUIT (tunneldiode); 00215 REGISTER_CIRCUIT (msline); 00216 REGISTER_CIRCUIT (mscorner); 00217 REGISTER_CIRCUIT (msstep); 00218 REGISTER_CIRCUIT (msopen); 00219 REGISTER_CIRCUIT (msgap); 00220 REGISTER_CIRCUIT (msmbend); 00221 REGISTER_CIRCUIT (mscoupled); 00222 REGISTER_CIRCUIT (mslange); 00223 REGISTER_CIRCUIT (mstee); 00224 REGISTER_CIRCUIT (mscross); 00225 REGISTER_CIRCUIT (msvia); 00226 REGISTER_CIRCUIT (msrstub); 00227 REGISTER_CIRCUIT (bondwire); 00228 REGISTER_CIRCUIT (cpwline); 00229 REGISTER_CIRCUIT (cpwopen); 00230 REGISTER_CIRCUIT (cpwshort); 00231 REGISTER_CIRCUIT (cpwgap); 00232 REGISTER_CIRCUIT (cpwstep); 00233 REGISTER_CIRCUIT (iprobe); 00234 REGISTER_CIRCUIT (vprobe); 00235 REGISTER_CIRCUIT (jfet); 00236 REGISTER_CIRCUIT (bjt); 00237 REGISTER_CIRCUIT (spfile); 00238 REGISTER_CIRCUIT (vnoise); 00239 REGISTER_CIRCUIT (inoise); 00240 REGISTER_CIRCUIT (mosfet); 00241 REGISTER_CIRCUIT (amplifier); 00242 REGISTER_CIRCUIT (opamp); 00243 REGISTER_CIRCUIT (iinoise); 00244 REGISTER_CIRCUIT (mutual); 00245 REGISTER_CIRCUIT (mutual2); 00246 REGISTER_CIRCUIT (mutualx); 00247 REGISTER_CIRCUIT (ivnoise); 00248 REGISTER_CIRCUIT (vvnoise); 00249 REGISTER_CIRCUIT (inverter); 00250 REGISTER_CIRCUIT (logicnor); 00251 REGISTER_CIRCUIT (logicor); 00252 REGISTER_CIRCUIT (logicnand); 00253 REGISTER_CIRCUIT (logicand); 00254 REGISTER_CIRCUIT (logicxnor); 00255 REGISTER_CIRCUIT (logicxor); 00256 REGISTER_CIRCUIT (digisource); 00257 REGISTER_CIRCUIT (buffer); 00258 REGISTER_CIRCUIT (hicumL2V2p1); 00259 REGISTER_CIRCUIT (HBT_X); 00260 REGISTER_CIRCUIT (mod_amp); 00261 REGISTER_CIRCUIT (hic2_full); 00262 REGISTER_CIRCUIT (log_amp); 00263 REGISTER_CIRCUIT (hic0_full); 00264 REGISTER_CIRCUIT (potentiometer); 00265 REGISTER_CIRCUIT (MESFET); 00266 REGISTER_CIRCUIT (EKV26MOS); 00267 REGISTER_CIRCUIT (bsim3v34nMOS); 00268 REGISTER_CIRCUIT (bsim3v34pMOS); 00269 REGISTER_CIRCUIT (bsim4v30nMOS); 00270 REGISTER_CIRCUIT (bsim4v30pMOS); 00271 REGISTER_CIRCUIT (hicumL0V1p2); 00272 REGISTER_CIRCUIT (hicumL0V1p2g); 00273 REGISTER_CIRCUIT (hicumL0V1p3); 00274 REGISTER_CIRCUIT (hicumL2V2p23); 00275 REGISTER_CIRCUIT (hicumL2V2p24); 00276 REGISTER_CIRCUIT (hicumL2V2p31n); 00277 REGISTER_CIRCUIT (photodiode); 00278 REGISTER_CIRCUIT (phototransistor); 00279 REGISTER_CIRCUIT (nigbt); 00280 REGISTER_CIRCUIT (dff_SR); 00281 REGISTER_CIRCUIT (tff_SR); 00282 REGISTER_CIRCUIT (jkff_SR); 00283 REGISTER_CIRCUIT (gatedDlatch); 00284 REGISTER_CIRCUIT (logic_1); 00285 REGISTER_CIRCUIT (logic_0); 00286 REGISTER_CIRCUIT (mux2to1); 00287 REGISTER_CIRCUIT (mux4to1); 00288 REGISTER_CIRCUIT (mux8to1); 00289 REGISTER_CIRCUIT (DLS_nto1); 00290 REGISTER_CIRCUIT (DLS_1ton); 00291 REGISTER_CIRCUIT (andor4x2); 00292 REGISTER_CIRCUIT (andor4x3); 00293 REGISTER_CIRCUIT (andor4x4); 00294 REGISTER_CIRCUIT (dmux2to4); 00295 REGISTER_CIRCUIT (dmux3to8); 00296 REGISTER_CIRCUIT (dmux4to16); 00297 REGISTER_CIRCUIT (ha1b); 00298 REGISTER_CIRCUIT (fa1b); 00299 REGISTER_CIRCUIT (fa2b); 00300 REGISTER_CIRCUIT (pad2bit); 00301 REGISTER_CIRCUIT (pad3bit); 00302 REGISTER_CIRCUIT (pad4bit); 00303 REGISTER_CIRCUIT (binarytogrey4bit); 00304 REGISTER_CIRCUIT (greytobinary4bit); 00305 REGISTER_CIRCUIT (comp_1bit); 00306 REGISTER_CIRCUIT (comp_2bit); 00307 REGISTER_CIRCUIT (comp_4bit); 00308 REGISTER_CIRCUIT (hpribin4bit); 00309 REGISTER_CIRCUIT (vcresistor); 00310 REGISTER_CIRCUIT (ecvs); 00311 00312 // analyses 00313 REGISTER_ANALYSIS (dcsolver); 00314 REGISTER_ANALYSIS (acsolver); 00315 REGISTER_ANALYSIS (spsolver); 00316 REGISTER_ANALYSIS (trsolver); 00317 REGISTER_ANALYSIS (hbsolver); 00318 REGISTER_ANALYSIS (parasweep); 00319 REGISTER_ANALYSIS (e_trsolver); 00320 } 00321 00322 // Global module unregistration. 00323 void module::unregisterModules (void) { 00324 qucs::hashiterator<module> it; 00325 for (it = qucs::hashiterator<module> (modules); *it; ++it) { 00326 delete it.currentVal (); 00327 } 00328 modules.clear (); 00329 } 00330 00331 #if DEBUG 00332 // header prefix 00333 static const char * def_prefix = 00334 "/*\n" 00335 " * qucsdefs.h - netlist definitions for the Qucs netlists\n" 00336 " *\n" 00337 " * This is free software; you can redistribute it and/or modify\n" 00338 " * it under the terms of the GNU General Public License as published by\n" 00339 " * the Free Software Foundation; either version 2, or (at your option)\n" 00340 " * any later version.\n" 00341 " * \n" 00342 " */\n" 00343 "\n" 00344 "#ifndef __QUCSDEFS_H__\n" 00345 "#define __QUCSDEFS_H__\n"; 00346 00347 // header suffix 00348 static const char * def_suffix = 00349 "\n" 00350 "#endif /* __QUCSDEFS_H__ */\n"; 00351 00352 // start of list of definitions 00353 static const char * def_start = 00354 "\n" 00355 "// List of available components.\n" 00356 "struct define_t qucs_definition_available[] =\n"; 00357 00358 // end of list entry 00359 static const char * def_stop = 00360 "\n" 00361 "static struct define_t def_End = {\n" 00362 " ((char *) 0), -1, 1, 0, 0, req_Def, opt_Def };\n"; 00363 00364 // Returns a compilable C-code string made from the given string. 00365 static char * printstr (const char * str) { 00366 static char txt[256]; 00367 int nostr = (str == PROP_NO_STR); 00368 sprintf (txt, "%s%s%s", 00369 (str && !nostr) ? "\"" : "", 00370 str ? nostr ? "((char *) -1)" : str : "((char *) 0)", 00371 (str && !nostr) ? "\"" : ""); 00372 return txt; 00373 } 00374 00375 // Prints a property list as compilable C-code. 00376 static void printprop (const char * type, const char * prefix, 00377 struct property_t * prop) { 00378 const char * key; 00379 const char ** str; 00380 const char * txt; 00381 fprintf (stdout, "static struct property_t %s_%s[] = {\n", prefix, type); 00382 do { 00383 key = prop->key; 00384 fprintf (stdout, " { %s, %d, ", printstr (key), prop->type); 00385 fprintf (stdout, "{ %g, %s }, ", prop->defaultval.d, 00386 printstr (prop->defaultval.s)); 00387 fprintf (stdout, "{ '%c', %g, %g, '%c',\n", 00388 prop->range.il, prop->range.l, prop->range.h, prop->range.ih); 00389 fprintf (stdout, " {"); 00390 str = prop->range.str; 00391 do { 00392 txt = *str; 00393 fprintf (stdout, " %s", printstr (txt)); 00394 if (txt) fprintf (stdout, ","); 00395 str++; 00396 } 00397 while (txt != NULL); 00398 fprintf (stdout, " } } }"); 00399 if (key) fprintf (stdout, ","); 00400 fprintf (stdout, "\n"); 00401 prop++; 00402 } 00403 while (key != NULL); 00404 fprintf (stdout, "};\n"); 00405 } 00406 00407 /* The function emits a complete list of the registered component 00408 definitions as compilable C-code. */ 00409 void module::print (void) { 00410 fprintf (stdout, "%s", def_prefix); 00411 qucs::hashiterator<module> it; 00412 for (it = qucs::hashiterator<module> (modules); *it; ++it) { 00413 module * m = it.currentVal (); 00414 struct define_t * def = m->definition; 00415 fprintf (stdout, "\n"); 00416 printprop (def->type, "req", def->required); 00417 fprintf (stdout, "\n"); 00418 printprop (def->type, "opt", def->optional); 00419 fprintf (stdout, "\n"); 00420 fprintf (stdout, "static struct define_t def_%s = {\n", def->type); 00421 fprintf (stdout, " %s, %d, %d, %d, %d, req_%s, opt_%s };\n", 00422 printstr (def->type), def->nodes, def->action, def->substrate, 00423 def->nonlinear, def->type, def->type); 00424 } 00425 fprintf (stdout, "%s", def_stop); 00426 fprintf (stdout, "%s", def_start); 00427 fprintf (stdout, "{\n"); 00428 for (it = qucs::hashiterator<module> (modules); *it; ++it) { 00429 module * m = it.currentVal (); 00430 struct define_t * def = m->definition; 00431 fprintf (stdout, " def_%s,\n", def->type); 00432 } 00433 fprintf (stdout, " def_End\n"); 00434 fprintf (stdout, "};\n"); 00435 fprintf (stdout, "%s", def_suffix); 00436 } 00437 #endif /* DEBUG */ 00438 00439 00440 // look for dynamic libs, load and register them 00441 void module::registerDynamicModules (char *proj, std::list<std::string> modlist) 00442 { 00443 /* How it is (WAS) supposed to work: 00444 * 1) It will list the working directory contents looking for libraries 00445 * 2) It will try to open each library and put its handle into a list 00446 * - Just by opening the lib it will already populate the factorycreate and factorydef 00447 * 3) The factory is iterated to create new modules and add them to the global hash 00448 * 00449 * TODO: 00450 * - Add destructor for loaded objects 00451 * - Add other methods to find the libraries 00452 * 00453 * Update 00454 * * project path is passed as paramter 00455 * * module names are passed as parameter 00456 */ 00457 00458 fprintf(stdout,"project location: %s\n", proj); 00459 fprintf(stdout,"modules to load: %lu\n", modlist.size()); 00460 00461 std::list<std::string>::iterator it; 00462 for (it=modlist.begin(); it!=modlist.end(); ++it) { 00463 00464 std::string absPathLib = proj; 00465 00466 #ifdef __APPLE__ 00467 absPathLib = absPathLib + "/" + *it + ".dylib"; 00468 #endif 00469 #ifdef __linux__ 00470 absPathLib = absPathLib + "/" + *it + ".so"; 00471 #endif 00472 #ifdef __MINGW32__ 00473 absPathLib = absPathLib + "\\" + *it + ".dll"; 00474 #endif 00475 00476 // which lib is going to be loaded 00477 fprintf( stdout, "try loading %s\n", absPathLib.c_str() ); 00478 00479 #if __MINGW32__ 00480 // Load the DLL 00481 HINSTANCE dlib = ::LoadLibrary(TEXT(absPathLib.c_str())); 00482 if (!dlib) { 00483 std::cerr << "Unable to load DLL!\n"; 00484 exit(-1); 00485 } 00486 #else //Linux and OSX 00487 // for some reason the RTLD_NOW alones makes dlopen 00488 // stick with the name (content) of the first loaded library 00489 void* dlib = dlopen(absPathLib.c_str(), RTLD_NOW|RTLD_LOCAL); 00490 if(dlib == NULL){ 00491 std::cerr << dlerror() << std::endl; 00492 exit(-1); 00493 } 00494 #endif 00495 00496 // add the handle to our list 00497 dl_list.insert(dl_list.end(), dlib); 00498 00499 } 00500 00501 // report on factorycreate 00502 std::cout << "factorycreate.size() is " << factorycreate.size() << '\n'; 00503 std::cout << "factorycreate has registered:"; 00504 00505 // print map key names/registered objects into factory 00506 std::map<std::string, creator_t *, std::less<std::string> >::iterator fitr; 00507 for (fitr=factorycreate.begin(); fitr!=factorycreate.end(); ++fitr) 00508 std::cout << ' ' << fitr->first; 00509 std::cout << '\n'; 00510 00511 // loop again over registered keys in factory and register into hash 00512 for (fitr=factorycreate.begin(); fitr!=factorycreate.end(); ++fitr) { 00513 00514 // fetch creator and definition by key name from factories 00515 circuit_creator_t mycreate = factorycreate[fitr->first]; 00516 define_t *mydefine = factorydef[fitr->first](); 00517 00518 /* 00519 printf("\n type: %s\n",mydefine->type ); 00520 printf(" nodes: %i\n",mydefine->nodes ); 00521 printf(" action: %i\n",mydefine->action ); 00522 printf(" required->key: %s\n",mydefine->required->key); 00523 */ 00524 00525 // modified registerModule to register dynamic loaded modules 00526 module * m = new module (); 00527 m->circreate = mycreate; 00528 m->definition = mydefine; 00529 00530 if (modules.get ((char *) mydefine->type) != NULL) { 00531 logprint (LOG_ERROR, "load module already registered: %s\n", mydefine->type); 00532 } 00533 else { 00534 modules.put ((char *) mydefine->type, m); 00535 } 00536 } 00537 00538 // print registered components 00539 /* 00540 qucs::hashiterator<module> it; 00541 for (it = qucs::hashiterator<module> (module::modules); *it; ++it) { 00542 module * m = it.currentVal (); 00543 struct define_t * def = m->definition; 00544 printf("\n" ); 00545 printf("type: %s\n",def->type ); 00546 printf("\n" ); 00547 } 00548 */ 00549 00550 } 00551 00552 // Close all the dynamic libs if any opened 00553 void module::closeDynamicLibs() 00554 { 00555 for(itr=dl_list.begin(); itr!=dl_list.end(); itr++){ 00556 #if __MINGW32__ 00557 FreeLibrary(*itr); 00558 #else 00559 dlclose(*itr); 00560 #endif 00561 } 00562 }