2c92b2561358324c464bd5f5eac92b3f7937960d
[tas-yagle.git] / distrib / sources / api / api / api_util.c
1 #include <dlfcn.h>
2 #include <tcl.h>
3 #include API_H
4 #include AVT_H
5
6 #ifndef LIB_PATH
7 #define LIB_PATH "cells"
8 #endif
9
10 // pour ajouter une autre lib, ajouter ':'<lib>
11 #define DEFAULT_LIBS "gen_builtin_functions.so:gen_API.so:beg_API.so:ctk_API.so:"\
12 "database_API.so:fcl_API.so:mbk_API.so:"\
13 "sim_API.so:spi_API.so:stm_API.so:ttv_API.so"
14
15 chain_list *API_DEFINES=NULL;
16 chain_list *API_ACTION_INIT=NULL;
17 chain_list *API_ACTION_END=NULL;
18 chain_list *API_ACTION_RESTART=NULL;
19 chain_list *API_ACTION_TOPLEVEL=NULL;
20 int token_already_taken=0;
21
22 /* ------------------------------------------------------------------------- */
23
24 t_arg *NewArg ()
25 {
26 return (t_arg*)mbkalloc (sizeof (struct t_arg));
27 }
28
29 /* ------------------------------------------------------------------------- */
30
31 int TypeCheck (t_arg *arg, char *type)
32 {
33 return strcmp (arg->TYPE, type);
34 }
35
36 /* ------------------------------------------------------------------------- */
37
38 int GetPointer (t_arg *arg)
39 {
40 return arg->POINTER;
41 }
42
43 /* ------------------------------------------------------------------------- */
44
45 void SetPointer (t_arg *arg, int p)
46 {
47 arg->POINTER = p;
48 }
49
50 /* ------------------------------------------------------------------------- */
51
52 void SetType (t_arg *arg, char *t)
53 {
54 arg->TYPE = mbkstrdup (t);
55 }
56
57
58 void *grab_special_function(char *prefix, char *name)
59 {
60 char temp[1024], *c;
61 void *func;
62 sprintf(temp,"wrap_%s",prefix);
63 if ((c=strrchr(temp,'.'))!=NULL)
64 *c='\0';
65 strcat(temp,name);
66 func=GetDynamicFunction(temp);
67 return func;
68 }
69
70 void *nowrap_grab_special_function(char *prefix, char *name)
71 {
72 char temp[1024], *c;
73 void *func;
74 strcpy(temp,prefix);
75 if ((c=strrchr(temp,'.'))!=NULL)
76 *c='\0';
77 strcat(temp,name);
78 func=GetDynamicFunction(temp);
79 return func;
80 }
81
82 //typedef int (*libfunc_type)(t_arg **ret, t_arg **prm, int n_params, char *errstr);
83 //typedef void (*voidfunc)();
84 typedef t_arg ** (*targfunc)(int *);
85
86 void grab_special_functions(char *prefix)
87 {
88 libfunc_type func;
89 targfunc func0;
90 char buf[256];
91 t_arg *ret;
92
93 func=grab_special_function(prefix,"_AtLoad_Initialize");
94 if (func!=NULL)
95 {
96 if (func(&ret, NULL, 0 , buf)!=0)
97 {
98 avt_errmsg(API_ERRMSG, "001", AVT_ERROR, prefix, buf);
99 //fprintf(stderr,"Error executing %s_AtLoad_Initialize() : %s\n", prefix, buf);
100 }
101 mbkfree(ret->TYPE);
102 free(ret);
103 }
104 func=grab_special_function(prefix,"_Action_Initialize");
105 if (func!=NULL) API_ACTION_INIT=addchain(API_ACTION_INIT, func);
106 func=grab_special_function(prefix,"_Action_Terminate");
107 if (func!=NULL) API_ACTION_END=addchain(API_ACTION_END, func);
108 func=grab_special_function(prefix,"_Restart");
109 if (func!=NULL) API_ACTION_RESTART=addchain(API_ACTION_RESTART, func);
110 func=grab_special_function(prefix,"_TopLevel");
111 if (func!=NULL) API_ACTION_TOPLEVEL=addchain(API_ACTION_TOPLEVEL, func);
112
113 func0=(targfunc)nowrap_grab_special_function(prefix, "_getdefines");
114 if (func0!=NULL)
115 {
116 t_arg **tmp;
117 int nb, i;
118 tmp=func0(&nb);
119 if (nb!=0)
120 {
121 for (i=0;i<nb;i++)
122 {
123 API_DEFINES=addchain(API_DEFINES, tmp[i]);
124 }
125 }
126 }
127 }
128 // non definitif
129 static int libs_are_already_loaded=0;
130
131 int trytoopenlib(char *path, char *name, char *mes, char *where)
132 {
133 char *tmp, newlibpath[4096], pwd[2048], *c;
134 // LD_LIBRARY_PATH first
135 if(dlopen(name,RTLD_LAZY|RTLD_GLOBAL)!=NULL) return 1;
136
137 // API PATH next
138 strcpy(newlibpath,path);
139 path=newlibpath;
140 tmp=strchr(newlibpath,':');
141 while (tmp!=NULL)
142 {
143 *tmp='\0';
144 strcpy(where,path);
145 sprintf(pwd,"%s/%s",path,name);
146 if(dlopen(pwd,RTLD_LAZY|RTLD_GLOBAL)!=NULL) return 1;
147 if (strlen(mes)==0 || strstr(mes," such ")!=NULL)
148 {
149 if ((c=dlerror())!=NULL)
150 strcpy(mes,c);
151 else
152 strcpy(mes,"unknown error");
153 }
154 tmp++;
155 path=tmp;
156 tmp=strchr(path,':');
157 }
158 strcpy(where,path);
159 sprintf(pwd,"%s/%s",path,name);
160 if(dlopen(pwd,RTLD_LAZY|RTLD_GLOBAL)!=NULL) return 1;
161 if (strlen(mes)==0 || strstr(mes," such ")!=NULL)
162 {
163 if ((c=dlerror())!=NULL)
164 strcpy(mes,c);
165 else
166 strcpy(mes,"unknown error");
167 }
168
169 return 0;
170 }
171
172 static char *getdistpath()
173 {
174 char *e;
175 char temp[4096];
176 e=getenv("AVT_TOOLS_DIR");
177 if (e==NULL)
178 {
179 e=getenv("AVT_DISTRIB_DIR");
180 if (e==NULL) return NULL;
181 sprintf(temp,"%s/api_lib",e);
182 return mbkstrdup(temp);
183 }
184 if (getenv("AVTOS")==NULL)
185 sprintf(temp,"%s/tools/Solaris/api_lib",e);
186 else
187 sprintf(temp,"%s/tools/%s/api_lib",e,getenv("AVTOS"));
188 return mbkstrdup(temp);
189 }
190
191 void LoadDynamicLibraries(FILE *debug)
192 {
193 char path[4096], *tpath, *libpath, libpath0[4096], *tmp, newlibpath[4096];
194 char message[4096], location[2048];
195 char *DEFAULT_LIB_PATH;
196
197 if (libs_are_already_loaded) return;
198 libs_are_already_loaded=1;
199
200 DEFAULT_LIB_PATH=getdistpath();
201 tpath=V_STR_TAB[__API_LIB_PATH].VALUE;
202 if (DEFAULT_LIB_PATH!=NULL)
203 {
204 if (tpath!=NULL)
205 sprintf(path,"%s:%s",tpath, DEFAULT_LIB_PATH);
206 else
207 strcpy(path,DEFAULT_LIB_PATH);
208 mbkfree(DEFAULT_LIB_PATH);
209 }
210 else
211 {
212 if (tpath!=NULL)
213 strcpy(path,tpath);
214 else
215 strcpy(path,".");
216 }
217
218 tpath=V_STR_TAB[__API_LIBS].VALUE;
219 if (tpath!=NULL)
220 {
221 sprintf(libpath0,"%s:%s",DEFAULT_LIBS,tpath);
222 libpath=libpath0;
223 }
224 else
225 libpath=DEFAULT_LIBS;
226
227 if (libpath!=NULL)
228 {
229 strcpy(newlibpath,libpath);
230 libpath=newlibpath;
231 tmp=strchr(newlibpath,':');
232 while (tmp!=NULL)
233 {
234 *tmp='\0';
235 #if 0
236 if (debug) fprintf(debug,"Opening dynamic library '%s' ... ",libpath);
237 strcpy(message,"");
238 if(!trytoopenlib(path,libpath, message, location))
239 {
240 if (debug)
241 {
242 fprintf(debug,"failed\n\t");
243 fprintf(debug,"%s\n",message);
244 }
245 else
246 avt_errmsg(API_ERRMSG, "002", AVT_WARNING, libpath, message);
247 // avt_fprintf(stderr,"[¤4warning¤.] could not open dynamic library '¤+%s¤.'\n\treason: %s\n", libpath, message);
248 grab_special_functions(libpath); // API en static peut etre
249 }
250 else
251 {
252 #endif
253 grab_special_functions(libpath);
254 #if 0
255 if (debug) fprintf(debug,"done (%s)\n",location);
256 }
257 #endif
258 tmp++;
259 libpath=tmp;
260 tmp=strchr(libpath,':');
261 }
262 #if 0
263 if (debug) fprintf(debug,"Opening dynamic library '%s' ... ",libpath);
264 strcpy(message,"");
265 if(!trytoopenlib(path,libpath,message,location))
266 {
267 if (debug)
268 {
269 fprintf(debug,"failed\n\t");
270 fprintf(debug,"%s\n",message);
271 }
272 else
273 avt_errmsg(API_ERRMSG, "002", AVT_WARNING, libpath, message);
274 // avt_fprintf(stderr,"[¤4warning¤.] could not open dynamic library '¤+%s¤.'\n\treason: %s\n", libpath, message);
275 grab_special_functions(libpath); // API en static peut etre
276 }
277 else
278 {
279 #endif
280 grab_special_functions(libpath);
281 #if 0
282 if (debug) fprintf(debug,"done (%s)\n",location);
283 }
284 #endif
285 }
286 }
287
288 void *GetDynamicFunction(char *function_name)
289 {
290 void *libfunc;
291 #ifdef RTLD_DEFAULT
292 libfunc=dlsym(RTLD_DEFAULT,function_name);
293 #else
294 libfunc=dlsym(NULL, function_name);
295 #endif
296 return libfunc;
297 }
298
299 char *getdistpath_2(char *temp)
300 {
301 char *e;
302 e=V_STR_TAB[__AVT_TEMPLATE_DIR].VALUE;
303 if (e==NULL)
304 {
305 e=getenv("AVT_TOOLS_DIR");
306 if (e==NULL)
307 {
308 strcpy(temp,".");
309 return temp;
310 }
311 sprintf(temp,"%s/gns_templates",e);
312 return temp;
313 }
314 strcpy(temp,e);
315 return temp;
316 }
317
318 static chain_list *splitenv()
319 {
320 char *e, *c, *start;
321 chain_list *cl=NULL;
322 char temp[1024];
323
324 e=V_STR_TAB[__GENIUS_LIB_PATH].VALUE;
325 if (e==NULL)
326 {
327 strcpy(temp, WORK_LIB);
328 strcat(temp, "/"LIB_PATH);
329 cl=addchain(cl, mbkstrdup(temp));
330 }
331 else
332 {
333 strcpy(temp, e);
334 start=temp;
335 c=strchr(start,':');
336 while (c!=NULL)
337 {
338 *c='\0';
339 cl=addchain(cl, mbkstrdup(start));
340 start=c+1;
341 c=strchr(start,':');
342 }
343 cl=addchain(cl, mbkstrdup(start));
344 }
345
346 cl=addchain(cl, mbkstrdup(getdistpath_2(temp)));
347
348 return reverse(cl);
349 }
350
351 static void freespitenv(chain_list *cl)
352 {
353 chain_list *ch;
354 for (ch=cl; ch!=NULL; ch=ch->NEXT)
355 mbkfree(ch->DATA);
356
357 freechain(cl);
358 }
359
360 static FILE *findfile(char *name, chain_list *paths, char *temp)
361 {
362 chain_list *cl;
363 FILE *f;
364
365 if (name[0]=='/')
366 {
367 strcpy(temp, name);
368 return mbkfopen(name,NULL, READ_TEXT);
369 }
370
371 for (cl=paths; cl!=NULL; cl=cl->NEXT)
372 {
373 sprintf(temp,"%s/%s", (char *)cl->DATA, name);
374 if ((f=mbkfopen(temp,NULL, READ_TEXT))!=NULL) break;
375 }
376 return f;
377 }
378
379 FILE *APIFindFile(lib_entry *p)
380 {
381 FILE *f;
382 char temp[2048];
383 chain_list *PATHS;
384
385 PATHS=splitenv();
386
387 f = findfile(p->name, PATHS, temp);
388
389 if (f!=NULL)
390 {
391 mbkfree(p->name);
392 p->name=mbkstrdup(temp);
393 }
394 freespitenv(PATHS);
395 return f;
396 }
397
398
399 int ReadAllCorVHDL(ExecutionContext *genius_ec, lib_entry *files_list, FILE *debug)
400 {
401 int err;
402 lib_entry *p;
403 tree_list *res;
404 FILE *f;
405 char temp[2048];
406 chain_list *PATHS;
407
408 PATHS=splitenv();
409
410 for (p=files_list;p;p=p->NEXT)
411 {
412 if (p->format==0)
413 {
414 if (strcasecmp(p->name,"none")!=0)
415 {
416 f = findfile(p->name, PATHS, temp);
417 if (f!=NULL)
418 {
419 char *r;
420 if (debug)
421 fprintf(debug, "Opening model file %s....\n",p->name);
422 mbkfree(p->name);
423 p->name=mbkstrdup(temp);
424 r=strrchr(p->name, '.');
425 if (r==NULL || strcasecmp(r, ".tcl")!=0)
426 res=APIParseFile(f, p->name, genius_ec, p->paramset);
427 else
428 {
429 int nb;
430 r=mbkalloc(1000000);
431 nb=fread(r,sizeof(char),1000000, f);
432 r[nb]='\0';
433 if (Tcl_EvalEx((Tcl_Interp *)TCL_INTERPRETER, r, -1, TCL_EVAL_GLOBAL)==TCL_ERROR)
434 avt_errmsg(GNS_ERRMSG, "165", AVT_ERROR, p->name, ((Tcl_Interp *)TCL_INTERPRETER)->errorLine, Tcl_GetStringResult((Tcl_Interp *)TCL_INTERPRETER));
435 mbkfree(r);
436 }
437
438 }
439 else
440 {
441 avt_errmsg(GNS_ERRMSG, "166", AVT_ERROR, p->name);
442 Inc_Error();
443 }
444 }
445 }
446 else
447 {
448 f = findfile(p->name, PATHS, temp);
449 if (f!=NULL)
450 {
451 mbkfree(p->name);
452 p->name=mbkstrdup(temp);
453 }
454 }
455 }
456 freespitenv(PATHS);
457 err = Get_Error();
458 if (err) return 1;
459 APIVerify_C_Functions (genius_ec);
460 if (APICheckCFunctions (genius_ec)) return 1;
461 return 0;
462 }
463
464 void APICallApiInitFunctions()
465 {
466 chain_list *p;
467 t_arg *ret;
468 libfunc_type func;
469 char buf[128];
470
471 for (p=API_ACTION_INIT; p!=NULL; p=p->NEXT)
472 {
473 func=(libfunc_type)p->DATA;
474 func(&ret, NULL, 0 , buf);
475 mbkfree(ret->TYPE); mbkfree(ret);
476 }
477 }
478
479 void APICallApiTerminateFunctions()
480 {
481 chain_list *p;
482 t_arg *ret;
483 libfunc_type func;
484 char buf[128];
485
486 for (p=API_ACTION_END; p!=NULL; p=p->NEXT)
487 {
488 func=(libfunc_type)p->DATA;
489 func(&ret, NULL, 0 , buf);
490 mbkfree(ret->TYPE); mbkfree(ret);
491 }
492 }
493
494 void APIPreprocess(char *src, char *dest, chain_list *defines)
495 {
496 char *cs, *cd, *start;
497 chain_list *cl;
498 api_define_type *adt;
499
500 cd=dest;
501 cs=src;
502
503 while (*cs!='$' && *cs!='\0') *(cd++)=*(cs++);
504 while (*cs!='\0')
505 {
506 cs++;
507 start=cs;
508 while (*cs>' ' && *cs!='$' && *cs!='\0') cs++;
509
510 cl=NULL;
511 if (*cs=='$')
512 {
513 *cs='\0';
514 for (cl=defines; cl!=NULL; cl=cl->NEXT)
515 {
516 adt=(api_define_type *)cl->DATA;
517 if (strcasecmp(adt->ORIG, start)==0) break;
518 }
519 *cs='$';
520 if (cl==NULL)
521 while (start!=cs) *(cd++)=*(start++);
522 else
523 {
524 for (start=adt->DEST; *start!='\0'; start++)
525 *(cd++)=*start;
526 }
527 cs++;
528 }
529 else
530 if (cs!='\0')
531 {
532 start--;
533 while (start!=cs) *(cd++)=*(start++);
534 *(cd++)=*start;
535 cs++;
536 }
537 while (*cs!='$' && *cs!='\0') *(cd++)=*(cs++);
538 }
539 *(cd++)='\0';
540 }
541
542 static ht *tclfunc=NULL;
543
544 int api_has_tcl_func(char *name)
545 {
546 long l;
547 Tcl_CmdInfo tci;
548 if (tclfunc==NULL) tclfunc=addht(10);
549 name=sensitive_namealloc(name);
550 if ((l=gethtitem(tclfunc, name))!=EMPTYHT)
551 return (int)l;
552
553 if (Tcl_GetCommandInfo((Tcl_Interp *)TCL_INTERPRETER, name, &tci)!=0) l=1;
554 else l=0;
555 addhtitem(tclfunc, name, l);
556 return l;
557 }