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

Contents of /trunk/pygtk/library.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1316 - (show annotations) (download) (as text)
Mon Mar 5 07:22:21 2007 UTC (13 years ago) by johnpye
File MIME type: text/x-c++src
File size: 9909 byte(s)
Another one of these big refactorings. Split out 'system' directory from 'solver' directory. This will need more work
but it's a start at getting the non-solver-specific code out separately.
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 char *x = Asc_GetEnv(PATHENVIRONMENTVAR);
61 if(x==NULL || strcmp(x,"")==0){
62 if(defaultpath==NULL){
63 ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,"Using default "
64 PATHENVIRONMENTVAR " = '" DEFAULT_ASCENDLIBRARY "'"
65 );
66 defaultpath = DEFAULT_ASCENDLIBRARY;
67 }
68
69 string s = string(PATHENVIRONMENTVAR "=") + defaultpath;
70 //ERROR_REPORTER_HERE(ASC_PROG_NOTE,"Setting %s",s.c_str());;
71 Asc_PutEnv(s.c_str());
72 }
73 Asc_ImportPathList(PATHENVIRONMENTVAR);
74 //cerr << PATHENVIRONMENTVAR << " = " << x << endl;
75 //cerr << "Created LIBRARY" << endl;
76 //cerr << "Registering solvers..." << endl;
77 registerStandardSolvers();
78 }/*else{
79 CONSOLE_DEBUG("Reusing LIBRARY");
80 }*/
81 have_init=1;
82 }
83
84 Library::~Library(){
85 //ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,"DESTROYED LIBRARY!////////////////////////////////////////");
86 //DestroyLibrary();
87 // ... need to use some kind of reference counting before you can do that...
88 }
89
90 /**
91 Load an ASCEND model file into the Library. It will be parsed such that
92 its types will be visible to Library::findType.
93
94 @param filename Filename, will be searched for relative to ASCENDLIBRARY environment
95 variable, if necessary.
96 */
97 void
98 Library::load(const char *filename){
99
100 //std::cerr << "Loading '" << filename << "'" << std::endl;
101
102 int status;
103 struct module_t *m=Asc_RequireModule(filename,&status);
104 if(m!=NULL){
105 //std::cerr << "Loaded module '" << Asc_ModuleName(m) << "'" << std::endl;
106 }else{
107 std::cerr << "Error: unable to load module '" << filename << "'." << std::endl;
108 }
109
110 char *msg;
111 switch(status){
112 case 5:
113 msg = "The module '%s' already exists. "; break;
114 case 4:
115 msg = "Caught an attempt to do a recursive require under '%s'."; break;
116 case 3:
117 msg = "A new module was created from '%s', overwriting a module's alias."; break;
118 case 2:
119 msg = "An existing module is being returned for '%s'." ; break;
120 case 1:
121 msg = "An new version of an existing module was created for '%s'."; break;
122 case 0:
123 msg = "Module for '%s' created OK."; break;
124 case -1:
125 msg = "File not found for '%s'. (-1)"; break;
126 case -2:
127 msg = "Unable to open '%s' for reading. (-2)";break;
128 case -3:
129 msg = "Insuffient memory to create module for '%s'. (-3)"; break;
130 case -4:
131 msg = "Bad input, null or zero length filename in '%s'. (-4)"; break;
132 default:
133 throw std::runtime_error("Invalid status code in library.cpp");
134 }
135
136 char msg1[100];
137 sprintf(msg1,msg,filename);
138
139 if(status<0 || status>0){
140 throw std::runtime_error(msg1);
141 }else{
142 std::cerr << "Note: Module " << Asc_ModuleName(m) << ": " << msg1 << std::endl;
143 }
144
145 CONSOLE_DEBUG("Beginning parse of %s",Asc_ModuleName(m));
146 error_reporter_tree_start();
147 status = zz_parse();
148 switch(status){
149 case 0: break;
150 case 1: ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Parsing of %s was aborted",Asc_ModuleName(m)); break;
151 case 2: ERROR_REPORTER_NOLINE(ASC_PROG_FATAL,"Out of memory when parsing %s",Asc_ModuleName(m)); break;
152 default: ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"Invalid return from zz_parse"); break;
153 }
154 status = error_reporter_tree_has_error();
155 error_reporter_tree_end();
156 if(!status){
157 CONSOLE_DEBUG("CLEARING TREE...");
158 error_reporter_tree_clear();
159 CONSOLE_DEBUG("DONE CLEARING TREE...");
160 }else{
161 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Error(s) when loading '%s'",filename);
162 stringstream ss;
163 ss << "Errors found in '" << filename << "'";
164 throw runtime_error(ss.str());
165 }
166
167
168 struct gl_list_t *l = Asc_TypeByModule(m);
169 CONSOLE_DEBUG("%lu library entries loaded from %s",gl_length(l), filename);
170 }
171
172 /**
173 Return a vector of all the Modules which have been loaded into
174 the current library.
175 */
176 vector<Module>
177 Library::getModules(const int module_type){
178 if(module_type < 0 || module_type > 2){
179 throw std::runtime_error("Library::getModules: invalid module_type parameter");
180 }
181
182 vector<Module> v;
183 struct gl_list_t *l = Asc_ModuleList(module_type);
184 if(l==NULL){
185 CONSOLE_DEBUG("list is empty");
186 return v;
187 }
188 for(int i=0, end=gl_length(l); i<end; ++i){
189 symchar *name = (symchar *)gl_fetch(l,i+1);
190 if(AscFindSymbol(name)==NULL){
191 throw runtime_error("Library::getModules: invalid symchar *");
192 }
193 //cerr << "GOT " << SCP( name ) << endl;
194 const module_t *m = Asc_GetModuleByName((const char *)name);
195 v.push_back(Module(m));
196 }
197 /*cerr << "LENGTH OF V IS " << v.size() << endl;
198 if(v.size()){
199 cerr << "MODULE 0's NAME IS " << v[0].getName() << endl;
200 }*/
201 return v;
202 }
203
204 /**
205 Output to stderr the names of the modules loaded into the current Library.
206 */
207 void
208 Library::listModules(const int module_type){
209 if(module_type < 0 || module_type > 2){
210 throw std::runtime_error("Library::listModules: invalid module_type parameter");
211 }
212
213 char *type = NULL;
214 switch(module_type){
215 case 0: type = "defined types"; break;
216 case 1: type = "string definitions"; break;
217 case 2: type = "statements"; break;
218 }
219
220 vector<Module> v = getModules(module_type);
221 if(v.size()){
222 std::cerr << "Listing " << v.size() << " modules with " << type << std::endl;
223 for(vector<Module>::const_iterator i=v.begin(); i < v.end(); ++i){
224 cerr << " - " << i->getName() << endl;
225 vector<Type> tt = getModuleTypes(*i);
226 for(vector<Type>::const_iterator j = tt.begin(); j < tt.end(); ++j){
227 cerr << " * " << j->getName() << endl;
228 }
229 }
230 }else{
231 std::cerr << "Notice: No " << type << " found in module list." << std::endl;
232 }
233 }
234
235 Type &
236 Library::findType(const SymChar &sym){
237 TypeDescription *t = FindType(sym.getInternalType());
238 if(t==NULL){
239 stringstream ss;
240 ss << "Library::findType: type '" << sym << "' not found in library";
241 throw runtime_error(ss.str());
242 }/*else{
243 cerr << "Found something for type " << sym << endl;
244 }*/
245 Type *t2=new Type(t);
246 return *t2;
247 }
248
249 /**
250 This could be quite a bit more efficient if we could get a gl_list_t of TypeDescription rather than names
251 */
252 vector<Type>
253 Library::getModuleTypes(const Module &m){
254 //cerr << "GET MODULE TYPES\n" << endl;
255 vector<Type> v;
256 struct gl_list_t *l = Asc_TypeByModule(m.getInternalType());
257 for(int i=0,end=gl_length(l); i<end; ++i){
258 char *name = (char *)gl_fetch(l,i+1);
259 //CONSOLE_DEBUG("Found type %s",name);
260 TypeDescription *t = FindType((const symchar *)name);
261 v.push_back(Type(t));
262 }
263 return v;
264 }
265
266 /**
267 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.
268 */
269 vector<ExtMethod>
270 Library::getExtMethods(){
271 // Clear the vector
272 extmethod_vector = vector<ExtMethod>();
273
274 // Traverse the vector
275 TraverseExtFuncLibrary(Library::extMethodTraverse, (void *)this);
276
277 return extmethod_vector;
278 }
279
280 /**
281 This method exists only to allow the TraverseExtFuncLibrary function
282 to make callbacks to the Library class from C.
283
284 @NOTE there might be issues with C/C++ linking here?
285 */
286 void
287 Library::extMethodTraverse(void *a1, void *a2){
288 Library *self = (Library *)a2;
289 self->appendToExtMethodVector(a1);
290 }
291
292 void
293 Library::appendToExtMethodVector(void *a1){
294 struct ExternalFunc *e = (struct ExternalFunc *)a1;
295 extmethod_vector.push_back(ExtMethod(e));
296 }
297
298 /**
299 Clear the library: 'DESTROY TYPES'
300
301 @TODO do this more efficiently, don't destroy the whole ASCEND compiler.
302 */
303 void
304 Library::clear(){
305 /* Asc_CompilerDestroy();
306 cerr << "COMPLETED ASC_COMPILERDESTROY" << endl;
307 Asc_CompilerInit(1);
308 cerr << "... ASC_COMPILERINIT OK" << endl;
309 Asc_ImportPathList(PATHENVIRONMENTVAR);
310 registerStandardSolvers();
311 cerr << "... REGISTER_STANDARD_SOLVERS" << endl;
312 DefineFundamentalTypes();
313 cerr << "... DEFINED FUND TYPES" << endl;
314 \*SetUniversalProcedureList(NULL);
315 */
316
317 //CONSOLE_DEBUG("Displaying library modules and types...");
318 //listModules();
319
320 CONSOLE_DEBUG("Destroying simulations...");
321 Asc_DestroySimulations();
322
323 CONSOLE_DEBUG("Clearing library...");
324 DestroyNotesDatabase(LibraryNote());
325 SetUniversalProcedureList(NULL);
326 DestroyLibrary();
327 DestroyPrototype();
328 EmptyTrash();
329 Asc_DestroyModules((DestroyFunc)DestroyStatementList);
330 //importhandler_destroylibrary();
331 WriteChildMissing(NULL,NULL,NULL);
332 //Asc_CompilerInit(1)
333 DefineFundamentalTypes();
334 InitNotesDatabase(LibraryNote());
335 ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,"LIBRARY CLEARED!");
336 }
337
338 AnnotationDatabase
339 Library::getAnnotationDatabase(){
340 return AnnotationDatabase(SCP(LibraryNote()));
341 }

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