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

Contents of /trunk/pygtk/library.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 931 - (show annotations) (download) (as text)
Thu Nov 23 04:31:19 2006 UTC (13 years, 2 months ago) by johnpye
File MIME type: text/x-c++src
File size: 9747 byte(s)
Added 'error_reporter_tree' that can organise error messages/output into a structured hierarchy.
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 #include <compiler/compiler.h>
15 #include <general/list.h>
16 #include <compiler/slist.h>
17 #include <compiler/ascCompiler.h>
18 #include <compiler/fractions.h>
19 #include <compiler/compiler.h>
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 <solver/slv_types.h>
32 #include <solver/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 = "Error: File not found for '%s'. (-1)"; break;
126 case -2:
127 msg = "Error: Unable to open '%s' for reading. (-2)";break;
128 case -3:
129 msg = "Error: Insuffient memory to create module for '%s'. (-3)"; break;
130 case -4:
131 msg = "Error: 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)error_reporter_tree_clear();
157 else{
158 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Error(s) when loading '%s'",filename);
159 stringstream ss;
160 ss << "Errors found in '" << filename << "'";
161 throw runtime_error(ss.str());
162 }
163
164
165 struct gl_list_t *l = Asc_TypeByModule(m);
166 CONSOLE_DEBUG("%lu library entries loaded from %s",gl_length(l), filename);
167 }
168
169 /**
170 Return a vector of all the Modules which have been loaded into
171 the current library.
172 */
173 vector<Module>
174 Library::getModules(){
175 //cerr << "GET MODULES\n" << endl;
176
177 vector<Module> v;
178 struct gl_list_t *l = Asc_ModuleList(0);
179 for(int i=0, end=gl_length(l); i<end; ++i){
180 symchar *name = (symchar *)gl_fetch(l,i+1);
181 if(AscFindSymbol(name)==NULL){
182 throw runtime_error("Library::getModules: invalid symchar *");
183 }
184 //cerr << "GOT " << SCP( name ) << endl;
185 const module_t *m = Asc_GetModuleByName((const char *)name);
186 v.push_back(Module(m));
187 }
188 /*cerr << "LENGTH OF V IS " << v.size() << endl;
189 if(v.size()){
190 cerr << "MODULE 0's NAME IS " << v[0].getName() << endl;
191 }*/
192 return v;
193 }
194
195 /**
196 Output to stderr the names of the modules loaded into the current Library.
197 */
198 void
199 Library::listModules(const int &module_type) const{
200
201 if(module_type < 0 || module_type > 2){
202 throw std::runtime_error("Library::listModules: invalid module_type parameter");
203 }
204
205 struct gl_list_t *l;
206
207 l = Asc_ModuleList(module_type);
208
209 if(l==NULL){
210 std::cerr << "Library::listModules: list is empty" << std::endl;
211 return;
212 //throw std::runtime_error("Library::listModules: Asc_ModuleList returned NULL");
213 }
214
215 char *type = NULL;
216 switch(module_type){
217 case 0: type = "modules containing defined types"; break;
218 case 1: type = "modules with string definitions"; break;
219 case 2: type = "modules with statements"; break;
220 }
221 int n=gl_length(l);
222 if(n){
223 std::cerr << "Listing " << gl_length(l) << " " << type << std::endl;
224 gl_iterate(l,Library::displayModule);
225 }else{
226 std::cerr << "Notice: No " << type << " found in module list." << std::endl;
227 }
228 }
229
230 void
231 Library::displayModule(void *v){
232 //module_t *m = (module_t *)v;
233 std::cerr << " - " << (char *)v << std::endl;
234 }
235
236 Type &
237 Library::findType(const SymChar &sym){
238 TypeDescription *t = FindType(sym.getInternalType());
239 if(t==NULL){
240 stringstream ss;
241 ss << "Library::findType: type '" << sym << "' not found in library";
242 throw runtime_error(ss.str());
243 }/*else{
244 cerr << "Found something for type " << sym << endl;
245 }*/
246 Type *t2=new Type(t);
247 return *t2;
248 }
249
250 /**
251 This could be quite a bit more efficient if we could get a gl_list_t of TypeDescription rather than names
252 */
253 vector<Type>
254 Library::getModuleTypes(const Module &m){
255 //cerr << "GET MODULE TYPES\n" << endl;
256 vector<Type> v;
257 struct gl_list_t *l = Asc_TypeByModule(m.getInternalType());
258 for(int i=0,end=gl_length(l); i<end; ++i){
259 char *name = (char *)gl_fetch(l,i+1);
260 //CONSOLE_DEBUG("Found type %s",name);
261 TypeDescription *t = FindType((const symchar *)name);
262 v.push_back(Type(t));
263 }
264 return v;
265 }
266
267 /**
268 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.
269 */
270 vector<ExtMethod>
271 Library::getExtMethods(){
272 // Clear the vector
273 extmethod_vector = vector<ExtMethod>();
274
275 // Traverse the vector
276 TraverseExtFuncLibrary(Library::extMethodTraverse, (void *)this);
277
278 return extmethod_vector;
279 }
280
281 /**
282 This method exists only to allow the TraverseExtFuncLibrary function
283 to make callbacks to the Library class from C.
284
285 @NOTE there might be issues with C/C++ linking here?
286 */
287 void
288 Library::extMethodTraverse(void *a1, void *a2){
289 Library *self = (Library *)a2;
290 self->appendToExtMethodVector(a1);
291 }
292
293 void
294 Library::appendToExtMethodVector(void *a1){
295 struct ExternalFunc *e = (struct ExternalFunc *)a1;
296 extmethod_vector.push_back(ExtMethod(e));
297 }
298
299 /**
300 Clear the library: 'DESTROY TYPES'
301
302 @TODO do this more efficiently, don't destroy the whole ASCEND compiler.
303 */
304 void
305 Library::clear(){
306 /* Asc_CompilerDestroy();
307 cerr << "COMPLETED ASC_COMPILERDESTROY" << endl;
308 Asc_CompilerInit(1);
309 cerr << "... ASC_COMPILERINIT OK" << endl;
310 Asc_ImportPathList(PATHENVIRONMENTVAR);
311 registerStandardSolvers();
312 cerr << "... REGISTER_STANDARD_SOLVERS" << endl;
313 DefineFundamentalTypes();
314 cerr << "... DEFINED FUND TYPES" << endl;
315 \*SetUniversalProcedureList(NULL);
316 */
317 ERROR_REPORTER_NOLINE(ASC_PROG_NOTE,"Destroying simulations...\n");
318 Asc_DestroySimulations();
319
320 ERROR_REPORTER_NOLINE(ASC_PROG_NOTE,"Clearing library...\n");
321 DestroyNotesDatabase(LibraryNote());
322 SetUniversalProcedureList(NULL);
323 DestroyLibrary();
324 DestroyPrototype();
325 EmptyTrash();
326 Asc_DestroyModules((DestroyFunc)DestroyStatementList);
327 WriteChildMissing(NULL,NULL,NULL);
328 //Asc_CompilerInit(1)
329 DefineFundamentalTypes();
330 InitNotesDatabase(LibraryNote());
331 ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,"LIBRARY CLEARED!");
332 }
333
334 AnnotationDatabase
335 Library::getAnnotationDatabase(){
336 return AnnotationDatabase(SCP(LibraryNote()));
337 }

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