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

Contents of /trunk/pygtk/library.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

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