/[ascend]/trunk/pygtk/library.cpp
ViewVC logotype

Contents of /trunk/pygtk/library.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1520 - (show annotations) (download) (as text)
Sat Jun 30 01:23:36 2007 UTC (12 years, 7 months ago) by jpye
File MIME type: text/x-c++src
File size: 9961 byte(s)
Fixing for missing yacc/lex on Windows, auto-update of them when yacc/lex *are* avail.
Fixing 'test.py' operation on Windows (ASCENDSOLVERS env var)
Adding missing ida.dll to installer.
Adding some missing export symbols in libascend.
1 #include <Python.h>
2
3 #include <iostream>
4 #include <stdexcept>
5 #include <sstream>
6 using namespace std;
7
8 #undef NDEBUG
9
10 #include "config.h"
11
12 extern "C"{
13 #include <utilities/ascConfig.h>
14
15 #include <general/list.h>
16 #include <compiler/slist.h>
17 #include <compiler/ascCompiler.h>
18 #include <compiler/fractions.h>
19
20 /* #include <compiler/redirectFile.h> */
21 #include <compiler/module.h>
22 #include <compiler/prototype.h>
23 #include <compiler/dump.h>
24 #include <compiler/dimen.h>
25 #include <compiler/child.h>
26 #include <compiler/childio.h>
27 #include <compiler/type_desc.h>
28 #include <compiler/typedef.h>
29 #include <compiler/library.h>
30 #include <compiler/childinfo.h>
31 #include <system/slv_types.h>
32 #include <system/system.h>
33 #include <utilities/ascEnvVar.h>
34 #include <compiler/symtab.h>
35 #include <general/table.h>
36 #include <compiler/instance_enum.h>
37 #include <compiler/notate.h>
38 #include <compiler/simlist.h>
39 #include <compiler/parser.h>
40 #include <utilities/error.h>
41 #include <general/env.h>
42 #include <compiler/importhandler.h>
43 }
44
45 #include "library.h"
46 #include "simulation.h"
47 #include "solver.h"
48
49 Library::Library(const char *defaultpath){
50 static int have_init;
51 if(!have_init){
52 //cerr << "Initialising ASCEND library..." << endl;
53
54 #ifdef REIMPLEMENT_STREAMS
55 Asc_RedirectCompilerDefault(); // Ensure that error message reach stderr
56 #endif
57
58 Asc_CompilerInit(1);
59 env_import(PATHENVIRONMENTVAR,getenv,Asc_PutEnv);
60 env_import(ASC_ASCENDSOLVERSVAR,getenv,Asc_PutEnv);
61
62 char *x = Asc_GetEnv(PATHENVIRONMENTVAR);
63 if(x==NULL || strcmp(x,"")==0){
64 if(defaultpath==NULL){
65 ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,"Using default "
66 PATHENVIRONMENTVAR " = '" DEFAULT_ASCENDLIBRARY "'"
67 );
68 defaultpath = DEFAULT_ASCENDLIBRARY;
69 }
70
71 string s = string(PATHENVIRONMENTVAR "=") + defaultpath;
72 //ERROR_REPORTER_HERE(ASC_PROG_NOTE,"Setting %s",s.c_str());;
73 Asc_PutEnv(s.c_str());
74 }
75 Asc_ImportPathList(PATHENVIRONMENTVAR);
76 //cerr << PATHENVIRONMENTVAR << " = " << x << endl;
77 //cerr << "Created LIBRARY" << endl;
78 //cerr << "Registering solvers..." << endl;
79 registerStandardSolvers();
80 }/*else{
81 CONSOLE_DEBUG("Reusing LIBRARY");
82 }*/
83 have_init=1;
84 }
85
86 Library::~Library(){
87 //ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,"DESTROYED LIBRARY!////////////////////////////////////////");
88 //DestroyLibrary();
89 // ... need to use some kind of reference counting before you can do that...
90 }
91
92 /**
93 Load an ASCEND model file into the Library. It will be parsed such that
94 its types will be visible to Library::findType.
95
96 @param filename Filename, will be searched for relative to ASCENDLIBRARY environment
97 variable, if necessary.
98 */
99 void
100 Library::load(const char *filename){
101
102 //std::cerr << "Loading '" << filename << "'" << std::endl;
103
104 int status;
105 struct module_t *m=Asc_RequireModule(filename,&status);
106 if(m!=NULL){
107 //std::cerr << "Loaded module '" << Asc_ModuleName(m) << "'" << std::endl;
108 }else{
109 std::cerr << "Error: unable to load module '" << filename << "'." << std::endl;
110 }
111
112 char *msg;
113 switch(status){
114 case 5:
115 msg = "The module '%s' already exists. "; break;
116 case 4:
117 msg = "Caught an attempt to do a recursive require under '%s'."; break;
118 case 3:
119 msg = "A new module was created from '%s', overwriting a module's alias."; break;
120 case 2:
121 msg = "An existing module is being returned for '%s'." ; break;
122 case 1:
123 msg = "An new version of an existing module was created for '%s'."; break;
124 case 0:
125 msg = "Module for '%s' created OK."; break;
126 case -1:
127 msg = "File not found for '%s'. (-1)"; break;
128 case -2:
129 msg = "Unable to open '%s' for reading. (-2)";break;
130 case -3:
131 msg = "Insuffient memory to create module for '%s'. (-3)"; break;
132 case -4:
133 msg = "Bad input, null or zero length filename in '%s'. (-4)"; break;
134 default:
135 throw std::runtime_error("Invalid status code in library.cpp");
136 }
137
138 char msg1[100];
139 sprintf(msg1,msg,filename);
140
141 if(status<0 || status>0){
142 throw std::runtime_error(msg1);
143 }else{
144 std::cerr << "Note: Module " << Asc_ModuleName(m) << ": " << msg1 << std::endl;
145 }
146
147 CONSOLE_DEBUG("Beginning parse of %s",Asc_ModuleName(m));
148 error_reporter_tree_start();
149 status = zz_parse();
150 switch(status){
151 case 0: break;
152 case 1: ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Parsing of %s was aborted",Asc_ModuleName(m)); break;
153 case 2: ERROR_REPORTER_NOLINE(ASC_PROG_FATAL,"Out of memory when parsing %s",Asc_ModuleName(m)); break;
154 default: ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"Invalid return from zz_parse"); break;
155 }
156 status = error_reporter_tree_has_error();
157 error_reporter_tree_end();
158 if(!status){
159 CONSOLE_DEBUG("CLEARING TREE...");
160 error_reporter_tree_clear();
161 CONSOLE_DEBUG("DONE CLEARING TREE...");
162 }else{
163 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Error(s) when loading '%s'",filename);
164 stringstream ss;
165 ss << "Errors found in '" << filename << "'";
166 throw runtime_error(ss.str());
167 }
168
169
170 struct gl_list_t *l = Asc_TypeByModule(m);
171 CONSOLE_DEBUG("%lu library entries loaded from %s",gl_length(l), filename);
172 }
173
174 /**
175 Return a vector of all the Modules which have been loaded into
176 the current library.
177 */
178 vector<Module>
179 Library::getModules(const int module_type){
180 if(module_type < 0 || module_type > 2){
181 throw std::runtime_error("Library::getModules: invalid module_type parameter");
182 }
183
184 vector<Module> v;
185 struct gl_list_t *l = Asc_ModuleList(module_type);
186 if(l==NULL){
187 CONSOLE_DEBUG("list is empty");
188 return v;
189 }
190 for(int i=0, end=gl_length(l); i<end; ++i){
191 symchar *name = (symchar *)gl_fetch(l,i+1);
192 if(AscFindSymbol(name)==NULL){
193 throw runtime_error("Library::getModules: invalid symchar *");
194 }
195 //cerr << "GOT " << SCP( name ) << endl;
196 const module_t *m = Asc_GetModuleByName((const char *)name);
197 v.push_back(Module(m));
198 }
199 /*cerr << "LENGTH OF V IS " << v.size() << endl;
200 if(v.size()){
201 cerr << "MODULE 0's NAME IS " << v[0].getName() << endl;
202 }*/
203 return v;
204 }
205
206 /**
207 Output to stderr the names of the modules loaded into the current Library.
208 */
209 void
210 Library::listModules(const int module_type){
211 if(module_type < 0 || module_type > 2){
212 throw std::runtime_error("Library::listModules: invalid module_type parameter");
213 }
214
215 char *type = NULL;
216 switch(module_type){
217 case 0: type = "defined types"; break;
218 case 1: type = "string definitions"; break;
219 case 2: type = "statements"; break;
220 }
221
222 vector<Module> v = getModules(module_type);
223 if(v.size()){
224 std::cerr << "Listing " << v.size() << " modules with " << type << std::endl;
225 for(vector<Module>::const_iterator i=v.begin(); i < v.end(); ++i){
226 cerr << " - " << i->getName() << endl;
227 vector<Type> tt = getModuleTypes(*i);
228 for(vector<Type>::const_iterator j = tt.begin(); j < tt.end(); ++j){
229 cerr << " * " << j->getName() << endl;
230 }
231 }
232 }else{
233 std::cerr << "Notice: No " << type << " found in module list." << std::endl;
234 }
235 }
236
237 Type &
238 Library::findType(const SymChar &sym){
239 TypeDescription *t = FindType(sym.getInternalType());
240 if(t==NULL){
241 stringstream ss;
242 ss << "Library::findType: type '" << sym << "' not found in library";
243 throw runtime_error(ss.str());
244 }/*else{
245 cerr << "Found something for type " << sym << endl;
246 }*/
247 Type *t2=new Type(t);
248 return *t2;
249 }
250
251 /**
252 This could be quite a bit more efficient if we could get a gl_list_t of TypeDescription rather than names
253 */
254 vector<Type>
255 Library::getModuleTypes(const Module &m){
256 //cerr << "GET MODULE TYPES\n" << endl;
257 vector<Type> v;
258 struct gl_list_t *l = Asc_TypeByModule(m.getInternalType());
259 for(int i=0,end=gl_length(l); i<end; ++i){
260 char *name = (char *)gl_fetch(l,i+1);
261 //CONSOLE_DEBUG("Found type %s",name);
262 TypeDescription *t = FindType((const symchar *)name);
263 v.push_back(Type(t));
264 }
265 return v;
266 }
267
268 /**
269 This function is kinda fighting against the Table implementation of the external function library. What we really need is some kind of iterator on the Table struct, but it doesn't seem to be implemented. Instead there is a C-style equivalent of the STL 'bind1st' function which we can use, but it's not exported from the current extfunc.h so we need to add it.
270 */
271 vector<ExtMethod>
272 Library::getExtMethods(){
273 // Clear the vector
274 extmethod_vector = vector<ExtMethod>();
275
276 // Traverse the vector
277 TraverseExtFuncLibrary(Library::extMethodTraverse, (void *)this);
278
279 return extmethod_vector;
280 }
281
282 /**
283 This method exists only to allow the TraverseExtFuncLibrary function
284 to make callbacks to the Library class from C.
285
286 @NOTE there might be issues with C/C++ linking here?
287 */
288 void
289 Library::extMethodTraverse(void *a1, void *a2){
290 Library *self = (Library *)a2;
291 self->appendToExtMethodVector(a1);
292 }
293
294 void
295 Library::appendToExtMethodVector(void *a1){
296 struct ExternalFunc *e = (struct ExternalFunc *)a1;
297 extmethod_vector.push_back(ExtMethod(e));
298 }
299
300 /**
301 Clear the library: 'DESTROY TYPES'
302
303 @TODO do this more efficiently, don't destroy the whole ASCEND compiler.
304 */
305 void
306 Library::clear(){
307 /* Asc_CompilerDestroy();
308 cerr << "COMPLETED ASC_COMPILERDESTROY" << endl;
309 Asc_CompilerInit(1);
310 cerr << "... ASC_COMPILERINIT OK" << endl;
311 Asc_ImportPathList(PATHENVIRONMENTVAR);
312 registerStandardSolvers();
313 cerr << "... REGISTER_STANDARD_SOLVERS" << endl;
314 DefineFundamentalTypes();
315 cerr << "... DEFINED FUND TYPES" << endl;
316 \*SetUniversalProcedureList(NULL);
317 */
318
319 //CONSOLE_DEBUG("Displaying library modules and types...");
320 //listModules();
321
322 CONSOLE_DEBUG("Destroying simulations...");
323 Asc_DestroySimulations();
324
325 CONSOLE_DEBUG("Clearing library...");
326 DestroyNotesDatabase(LibraryNote());
327 SetUniversalProcedureList(NULL);
328 DestroyLibrary();
329 DestroyPrototype();
330 EmptyTrash();
331 Asc_DestroyModules((DestroyFunc)DestroyStatementList);
332 //importhandler_destroylibrary();
333 WriteChildMissing(NULL,NULL,NULL);
334 //Asc_CompilerInit(1)
335 DefineFundamentalTypes();
336 InitNotesDatabase(LibraryNote());
337 ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,"LIBRARY CLEARED!");
338 }
339
340 AnnotationDatabase
341 Library::getAnnotationDatabase(){
342 return AnnotationDatabase(SCP(LibraryNote()));
343 }

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22