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

Contents of /trunk/pygtk/library.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

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