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

Annotation of /trunk/pygtk/library.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1524 - (hide annotations) (download) (as text)
Sat Jun 30 23:21:49 2007 UTC (15 years, 8 months ago) by jpye
File MIME type: text/x-c++src
File size: 9941 byte(s)
changed to ASC_ENV_SOLVERS and ASC_ENV_LIBRARY in C code.
Rerranged order of Tcl/Tk initialisation so that path env vars are set before solvers are loaded.
1 johnpye 912 #include <Python.h>
2    
3 johnpye 132 #include <iostream>
4     #include <stdexcept>
5     #include <sstream>
6     using namespace std;
7    
8     #undef NDEBUG
9    
10 johnpye 480 #include "config.h"
11 johnpye 507
12 johnpye 132 extern "C"{
13 johnpye 190 #include <utilities/ascConfig.h>
14 johnpye 1210
15 johnpye 132 #include <general/list.h>
16     #include <compiler/slist.h>
17 johnpye 190 #include <compiler/ascCompiler.h>
18     #include <compiler/fractions.h>
19 johnpye 1210
20 johnpye 929 /* #include <compiler/redirectFile.h> */
21 johnpye 132 #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 johnpye 1316 #include <system/slv_types.h>
32     #include <system/system.h>
33 johnpye 132 #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 johnpye 164 #include <compiler/simlist.h>
39 johnpye 480 #include <compiler/parser.h>
40 johnpye 485 #include <utilities/error.h>
41 johnpye 692 #include <general/env.h>
42 johnpye 875 #include <compiler/importhandler.h>
43 johnpye 132 }
44    
45     #include "library.h"
46     #include "simulation.h"
47     #include "solver.h"
48    
49 johnpye 481 Library::Library(const char *defaultpath){
50 johnpye 132 static int have_init;
51     if(!have_init){
52 johnpye 1150 //cerr << "Initialising ASCEND library..." << endl;
53 johnpye 929
54     #ifdef REIMPLEMENT_STREAMS
55 johnpye 132 Asc_RedirectCompilerDefault(); // Ensure that error message reach stderr
56 johnpye 929 #endif
57    
58 johnpye 132 Asc_CompilerInit(1);
59 jpye 1524 env_import(ASC_ENV_LIBRARY,getenv,Asc_PutEnv);
60     env_import(ASC_ENV_SOLVERS,getenv,Asc_PutEnv);
61 jpye 1520
62 jpye 1524 char *x = Asc_GetEnv(ASC_ENV_LIBRARY);
63 johnpye 341 if(x==NULL || strcmp(x,"")==0){
64 johnpye 692 if(defaultpath==NULL){
65     ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,"Using default "
66 jpye 1524 ASC_ENV_LIBRARY " = '" DEFAULT_ASCENDLIBRARY "'"
67 johnpye 692 );
68     defaultpath = DEFAULT_ASCENDLIBRARY;
69     }
70 jpye 1520
71 jpye 1524 string s = string(ASC_ENV_LIBRARY "=") + defaultpath;
72 johnpye 803 //ERROR_REPORTER_HERE(ASC_PROG_NOTE,"Setting %s",s.c_str());;
73 johnpye 341 Asc_PutEnv(s.c_str());
74     }
75 jpye 1524 Asc_ImportPathList(ASC_ENV_LIBRARY);
76 johnpye 803 //cerr << PATHENVIRONMENTVAR << " = " << x << endl;
77 johnpye 500 //cerr << "Created LIBRARY" << endl;
78 johnpye 803 //cerr << "Registering solvers..." << endl;
79 johnpye 132 registerStandardSolvers();
80 johnpye 973 }/*else{
81 johnpye 897 CONSOLE_DEBUG("Reusing LIBRARY");
82 johnpye 973 }*/
83 johnpye 132 have_init=1;
84     }
85    
86     Library::~Library(){
87 johnpye 1240 //ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,"DESTROYED LIBRARY!////////////////////////////////////////");
88 johnpye 175 //DestroyLibrary();
89 johnpye 190 // ... need to use some kind of reference counting before you can do that...
90 johnpye 132 }
91    
92 johnpye 180 /**
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 johnpye 132 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 johnpye 1041 msg = "File not found for '%s'. (-1)"; break;
128 johnpye 190 case -2:
129 johnpye 1041 msg = "Unable to open '%s' for reading. (-2)";break;
130 johnpye 132 case -3:
131 johnpye 1041 msg = "Insuffient memory to create module for '%s'. (-3)"; break;
132 johnpye 132 case -4:
133 johnpye 1041 msg = "Bad input, null or zero length filename in '%s'. (-4)"; break;
134 johnpye 132 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 johnpye 931 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 johnpye 932 if(!status){
159     CONSOLE_DEBUG("CLEARING TREE...");
160     error_reporter_tree_clear();
161     CONSOLE_DEBUG("DONE CLEARING TREE...");
162     }else{
163 johnpye 931 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 johnpye 132
169 johnpye 931
170 johnpye 132 struct gl_list_t *l = Asc_TypeByModule(m);
171 johnpye 897 CONSOLE_DEBUG("%lu library entries loaded from %s",gl_length(l), filename);
172 johnpye 132 }
173    
174 johnpye 180 /**
175     Return a vector of all the Modules which have been loaded into
176     the current library.
177     */
178 johnpye 132 vector<Module>
179 johnpye 973 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 johnpye 132
184     vector<Module> v;
185 johnpye 973 struct gl_list_t *l = Asc_ModuleList(module_type);
186     if(l==NULL){
187     CONSOLE_DEBUG("list is empty");
188     return v;
189     }
190 johnpye 132 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 johnpye 180 /**
207     Output to stderr the names of the modules loaded into the current Library.
208     */
209 johnpye 132 void
210 johnpye 973 Library::listModules(const int module_type){
211 johnpye 132 if(module_type < 0 || module_type > 2){
212     throw std::runtime_error("Library::listModules: invalid module_type parameter");
213     }
214    
215 johnpye 782 char *type = NULL;
216 johnpye 132 switch(module_type){
217 johnpye 973 case 0: type = "defined types"; break;
218     case 1: type = "string definitions"; break;
219     case 2: type = "statements"; break;
220 johnpye 132 }
221 johnpye 973
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 johnpye 132 }else{
233     std::cerr << "Notice: No " << type << " found in module list." << std::endl;
234     }
235     }
236    
237     Type &
238 johnpye 897 Library::findType(const SymChar &sym){
239 johnpye 132 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 johnpye 150 //CONSOLE_DEBUG("Found type %s",name);
262 johnpye 132 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 johnpye 213 vector<ExtMethod>
272     Library::getExtMethods(){
273 johnpye 132 // Clear the vector
274 johnpye 213 extmethod_vector = vector<ExtMethod>();
275 johnpye 132
276     // Traverse the vector
277 johnpye 213 TraverseExtFuncLibrary(Library::extMethodTraverse, (void *)this);
278 johnpye 132
279 johnpye 213 return extmethod_vector;
280 johnpye 132 }
281    
282 johnpye 180 /**
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 johnpye 132 void
289 johnpye 213 Library::extMethodTraverse(void *a1, void *a2){
290 johnpye 132 Library *self = (Library *)a2;
291 johnpye 213 self->appendToExtMethodVector(a1);
292 johnpye 132 }
293    
294     void
295 johnpye 213 Library::appendToExtMethodVector(void *a1){
296 johnpye 132 struct ExternalFunc *e = (struct ExternalFunc *)a1;
297 johnpye 213 extmethod_vector.push_back(ExtMethod(e));
298 johnpye 132 }
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 johnpye 711 \*SetUniversalProcedureList(NULL);
317 johnpye 132 */
318 johnpye 973
319     //CONSOLE_DEBUG("Displaying library modules and types...");
320     //listModules();
321    
322 johnpye 932 CONSOLE_DEBUG("Destroying simulations...");
323 johnpye 164 Asc_DestroySimulations();
324    
325 johnpye 932 CONSOLE_DEBUG("Clearing library...");
326 johnpye 132 DestroyNotesDatabase(LibraryNote());
327 johnpye 161 SetUniversalProcedureList(NULL);
328 johnpye 132 DestroyLibrary();
329     DestroyPrototype();
330     EmptyTrash();
331     Asc_DestroyModules((DestroyFunc)DestroyStatementList);
332 johnpye 1027 //importhandler_destroylibrary();
333 johnpye 132 WriteChildMissing(NULL,NULL,NULL);
334     //Asc_CompilerInit(1)
335     DefineFundamentalTypes();
336     InitNotesDatabase(LibraryNote());
337 johnpye 190 ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,"LIBRARY CLEARED!");
338 johnpye 132 }
339    
340 johnpye 897 AnnotationDatabase
341     Library::getAnnotationDatabase(){
342     return AnnotationDatabase(SCP(LibraryNote()));
343     }

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