source: git/Singular/iplib.cc @ 938688

spielwiese
Last change on this file since 938688 was 938688, checked in by Hans Schönemann <hannes@…>, 20 years ago
*hannes:2-1 new dir:kernel git-svn-id: file:///usr/local/Singular/svn/trunk@6915 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 31.7 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: iplib.cc,v 1.104 2003-11-04 16:43:29 Singular Exp $ */
5/*
6* ABSTRACT: interpreter: LIB and help
7*/
8
9//#include <stdlib.h>
10#include <stdio.h>
11#include <string.h>
12#include <ctype.h>
13#include <sys/stat.h>
14
15#include "mod2.h"
16#include "static.h"
17#include "tok.h"
18#include "ipid.h"
19#include "omalloc.h"
20#include "febase.h"
21#include "ring.h"
22#include "subexpr.h"
23#include "ipshell.h"
24#include "lists.h"
25
26BOOLEAN load_modules(char *newlib, char *fullname, BOOLEAN tellerror);
27
28#ifdef HAVE_LIBPARSER
29#  include "libparse.h"
30#else /* HAVE_LIBPARSER */
31   procinfo *iiInitSingularProcinfo(procinfov pi, char *libname,
32                                    char *procname, int line, long pos,
33                                    BOOLEAN pstatic = FALSE);
34#endif /* HAVE_LIBPARSER */
35#define NS_LRING (procstack->cRing)
36
37#include "mod_raw.h"
38
39static char *iiConvName(const char *p);
40#ifdef HAVE_LIBPARSER
41void yylprestart (FILE *input_file );
42int current_pos(int i=0);
43extern int yylp_errno;
44extern int yylplineno;
45extern char *yylp_errlist[];
46void print_init();
47libstackv library_stack;
48#endif
49
50//int IsCmd(char *n, int tok);
51char mytolower(char c);
52
53/*2
54* return TRUE if the libray libname is already loaded
55*/
56BOOLEAN iiGetLibStatus(char *lib)
57{
58  idhdl hl;
59
60#ifndef HAVE_NS
61  char *p;
62
63  hl = IDROOT->get("LIB", 0);
64  if (hl == NULL || (p=strstr(IDSTRING(hl), lib)) == NULL) return FALSE;
65  if ((p!=IDSTRING(hl)) && (*(p-1)!=',')) return FALSE;
66
67  return TRUE;
68#else
69  char *plib = iiConvName(lib);
70  hl = basePack->idroot->get(plib,0);
71  if((hl==NULL) ||(IDTYP(hl)!=PACKAGE_CMD))
72  {
73    omFree(plib);
74    return FALSE;
75  }
76  omFree(plib);
77  return (strcmp(lib,IDPACKAGE(hl)->libname)==0);
78#endif
79}
80
81/*2
82* find the library of an proc:
83*  => return (pi->libname)
84*/
85char * iiGetLibName(procinfov pi)
86{
87  return pi->libname;
88}
89
90/*2
91* given a line 'proc[ ]+{name}[ \t]*'
92* return a pointer to name and set the end of '\0'
93* changes the input!
94* returns: e: pointer to 'end of name'
95*          ct: changed char at the end of s
96*/
97char* iiProcName(char *buf, char & ct, char* &e)
98{
99  char *s=buf+5;
100  while (*s==' ') s++;
101  e=s+1;
102  while ((*e>' ') && (*e!='(')) e++;
103  ct=*e;
104  *e='\0';
105  return s;
106}
107
108/*2
109* given a line with args, return the argstr
110*/
111char * iiProcArgs(char *e,BOOLEAN withParenth)
112{
113  while ((*e==' ') || (*e=='\t') || (*e=='(')) e++;
114  if (*e<' ')
115  {
116    if (withParenth)
117    {
118      // no argument list, allow list #
119      return omStrDup("parameter list #;");
120    }
121    else
122    {
123      // empty list
124      return omStrDup("");
125    }
126  }
127  BOOLEAN in_args;
128  BOOLEAN args_found;
129  char *s;
130  char *argstr=(char *)omAlloc(127); // see ../omalloc/omTables.inc
131  int argstrlen=127;
132  *argstr='\0';
133  int par=0;
134  do
135  {
136    args_found=FALSE;
137    s=e; // set s to the starting point of the arg
138         // and search for the end
139    while ((*e!=',')
140    &&((par!=0) || (*e!=')'))
141    &&(*e!='\0'))
142    {
143      if (*e=='(') par++;
144      else if (*e==')') par--;
145      args_found=args_found || (*e>' ');
146      e++;
147    }
148    in_args=(*e==',');
149    if (args_found)
150    {
151      *e='\0';
152      // check for space:
153      if ((int)strlen(argstr)+12 /* parameter + ;*/ +(int)strlen(s)>= argstrlen)
154      {
155        argstrlen*=2;
156        char *a=(char *)omAlloc( argstrlen);
157        strcpy(a,argstr);
158        omFree((ADDRESS)argstr);
159        argstr=a;
160      }
161      // copy the result to argstr
162      strcat(argstr,"parameter ");
163      strcat(argstr,s);
164      strcat(argstr,"; ");
165      e++; // e was pointing to ','
166    }
167  } while (in_args);
168  return argstr;
169}
170
171/*2
172* locate `procname` in lib `libname` and find the part `part`:
173*  part=0: help, between, but excluding the line "proc ..." and "{...":
174*    => return
175*  part=1: body, between "{ ..." and "}", including the 1. line, w/o "{"
176*    => set pi->data.s.body, return NULL
177*  part=2: example, between, but excluding the line "exapmle {..." and "}":
178*    => return
179*/
180char* iiGetLibProcBuffer(procinfo *pi, int part )
181{
182  char buf[256], *s = NULL, *p;
183  long procbuflen;
184
185  FILE * fp = feFopen( pi->libname, "rb", NULL, TRUE );
186  if (fp==NULL)
187  {
188    return NULL;
189  }
190
191  fseek(fp, pi->data.s.proc_start, SEEK_SET);
192  if(part==0)
193  { // load help string
194    int i, offset=0;
195    long head = pi->data.s.def_end - pi->data.s.proc_start;
196    procbuflen = pi->data.s.help_end - pi->data.s.help_start;
197    if (procbuflen<5)
198      return NULL; // help part does not exist
199    //Print("Help=%ld-%ld=%d\n", pi->data.s.body_start,
200    //    pi->data.s.proc_start, procbuflen);
201    s = (char *)omAlloc(procbuflen+head+3);
202    myfread(s, head, 1, fp);
203    s[head] = '\n';
204    fseek(fp, pi->data.s.help_start, SEEK_SET);
205    myfread(s+head+1, procbuflen, 1, fp);
206    s[procbuflen+head+1] = '\n';
207    s[procbuflen+head+2] = '\0';
208    offset=0;
209    for(i=0;i<=procbuflen+head+2; i++)
210    {
211      if(s[i]=='\\' &&
212         (s[i+1]=='"' || s[i+1]=='{' || s[i+1]=='}' || s[i+1]=='\\'))
213      {
214        i++;
215        offset++;
216      }
217      if(offset>0) s[i-offset] = s[i];
218    }
219    return(s);
220  }
221  else if(part==1)
222  { // load proc part - must exist
223    procbuflen = pi->data.s.def_end - pi->data.s.proc_start;
224    char *ss=(char *)omAlloc(procbuflen+2);
225    //fgets(buf, sizeof(buf), fp);
226    myfread( ss, procbuflen, 1, fp);
227    char ct;
228    char *e;
229    s=iiProcName(ss,ct,e);
230    char *argstr=NULL;
231    *e=ct;
232    argstr=iiProcArgs(e,TRUE);
233
234    assume(pi->data.s.body_end > pi->data.s.body_start);
235
236    procbuflen = pi->data.s.body_end - pi->data.s.body_start;
237    pi->data.s.body = (char *)omAlloc( strlen(argstr)+procbuflen+15+
238                                      strlen(pi->libname) );
239    //Print("Body=%ld-%ld=%d\n", pi->data.s.body_end,
240    //    pi->data.s.body_start, procbuflen);
241    assume(pi->data.s.body != NULL);
242    fseek(fp, pi->data.s.body_start, SEEK_SET);
243    strcpy(pi->data.s.body,argstr);
244    myfread( pi->data.s.body+strlen(argstr), procbuflen, 1, fp);
245    procbuflen+=strlen(argstr);
246    omFree(argstr);
247    omFree(ss);
248    fclose( fp );
249    pi->data.s.body[procbuflen] = '\0';
250    strcat( pi->data.s.body+procbuflen, "\n;return();\n\n" );
251    strcat( pi->data.s.body+procbuflen+13,pi->libname);
252    s=strchr(pi->data.s.body,'{');
253    if (s!=NULL) *s=' ';
254    return NULL;
255  }
256  else if(part==2)
257  { // example
258    if ( pi->data.s.example_lineno == 0)
259      return NULL; // example part does not exist
260    // load example
261    fseek(fp, pi->data.s.example_start, SEEK_SET);
262    fgets(buf, sizeof(buf), fp); // skip line with "example"
263    procbuflen = pi->data.s.proc_end - pi->data.s.example_start - strlen(buf);
264    //Print("Example=%ld-%ld=%d\n", pi->data.s.proc_end,
265    //  pi->data.s.example_start, procbuflen);
266    s = (char *)omAlloc(procbuflen+14);
267    myfread(s, procbuflen, 1, fp);
268    s[procbuflen] = '\0';
269    strcat(s+procbuflen-3, "\n;return();\n\n" );
270    p=strchr(s,'{');
271    if (p!=NULL) *p=' ';
272    return(s);
273  }
274  return NULL;
275}
276
277/*2
278* start a proc
279* parameters are built as exprlist
280* TODO:interrupt
281* return FALSE on success, TRUE if an error occurs
282*/
283BOOLEAN iiPStart(idhdl pn, sleftv  * v)
284{
285  char * str;
286  BOOLEAN err=FALSE;
287  int old_echo=si_echo;
288  char save_flags=0;
289  procinfov pi=NULL;
290
291  /* init febase ======================================== */
292  /* we do not enter this case if filename != NULL !! */
293  if (pn!=NULL)
294  {
295    pi = IDPROC(pn);
296    if(pi!=NULL)
297    {
298      save_flags=pi->trace_flag;
299      if( pi->data.s.body==NULL )
300      {
301        iiGetLibProcBuffer(pi);
302        if (pi->data.s.body==NULL) return TRUE;
303      }
304      newBuffer( omStrDup(pi->data.s.body), BT_proc,
305                 pi, pi->data.s.body_lineno-(v!=NULL) );
306    }
307  }
308  /* generate argument list ======================================*/
309  if (v!=NULL)
310  {
311    iiCurrArgs=(leftv)omAllocBin(sleftv_bin);
312    memcpy(iiCurrArgs,v,sizeof(sleftv));
313    memset(v,0,sizeof(sleftv));
314  }
315  else
316  {
317    iiCurrArgs=NULL;
318  }
319  /* start interpreter ======================================*/
320  myynest++;
321  err=yyparse();
322#ifdef HAVE_NS
323  checkall();
324#endif
325  if (sLastPrinted.rtyp!=0)
326  {
327    sLastPrinted.CleanUp();
328  }
329  //Print("kill locals for %s (level %d)\n",IDID(pn),myynest);
330  killlocals(myynest);
331#ifdef HAVE_NS
332  checkall();
333#endif
334  //Print("end kill locals for %s (%d)\n",IDID(pn),myynest);
335  myynest--;
336  si_echo=old_echo;
337  if (pi!=NULL)
338    pi->trace_flag=save_flags;
339  return err;
340}
341
342#ifdef USE_IILOCALRING
343ring    *iiLocalRing;
344#endif
345sleftv  *iiRETURNEXPR;
346int     iiRETURNEXPR_len=0;
347
348#ifdef RDEBUG
349static void iiShowLevRings()
350{
351  int i;
352#ifdef USE_IILOCALRING
353  for (i=1;i<=myynest;i++)
354  {
355    Print("lev %d:",i);
356    if (iiLocalRing[i]==NULL) PrintS("NULL");
357    else                      Print("%d",iiLocalRing[i]);
358    PrintLn();
359  }
360#endif
361#if  0
362//#ifdef HAVE_NS
363  i=myynest;
364  proclevel *p=procstack;
365  while (p!=NULL)
366  {
367    Print("lev %d:",i);
368    if (p->cRingHdl==NULL) PrintS("NULL");
369    else                   Print("%s",IDID(p->cRingHdl));
370    PrintLn();
371    p=p->next;
372  }
373#endif
374  if (currRing==NULL) PrintS("curr:NULL\n");
375  else                Print ("curr:%x\n",currRing);
376}
377#endif /* RDEBUG */
378
379static void iiCheckNest()
380{
381  if (myynest >= iiRETURNEXPR_len-1)
382  {
383    iiRETURNEXPR=(sleftv *)omreallocSize(iiRETURNEXPR,
384                                   iiRETURNEXPR_len*sizeof(sleftv),
385                                   (iiRETURNEXPR_len+16)*sizeof(sleftv));
386    omMarkAsStaticAddr(iiRETURNEXPR);
387    memset(&(iiRETURNEXPR[iiRETURNEXPR_len]),0,16*sizeof(sleftv));
388#ifdef USE_IILOCALRING
389    iiLocalRing=(ring *)omreallocSize(iiLocalRing,
390                                   iiRETURNEXPR_len*sizeof(ring),
391                                   (iiRETURNEXPR_len+16)*sizeof(ring));
392    memset(&(iiLocalRing[iiRETURNEXPR_len]),0,16*sizeof(ring));
393#endif
394    iiRETURNEXPR_len+=16;
395  }
396}
397#ifdef HAVE_NS
398sleftv * iiMake_proc(idhdl pn, package pack, sleftv* sl)
399#else /* HAVE_NS */
400sleftv * iiMake_proc(idhdl pn, sleftv* sl)
401#endif /* HAVE_NS */
402{
403  int err;
404  procinfov pi = IDPROC(pn);
405  char *plib = iiConvName(pi->libname);
406  omFree((ADDRESS)plib);
407  if(pi->is_static && myynest==0)
408  {
409    Werror("'%s::%s()' is a local procedure and cannot be accessed by an user.",
410           pi->libname, pi->procname);
411    return NULL;
412  }
413  iiCheckNest();
414#ifdef USE_IILOCALRING
415  iiLocalRing[myynest]=currRing;
416#endif
417  iiRETURNEXPR[myynest+1].Init();
418  procstack->push(pi->procname);
419  if ((traceit&TRACE_SHOW_PROC)
420  || (pi->trace_flag&TRACE_SHOW_PROC))
421  {
422    if (traceit&TRACE_SHOW_LINENO) PrintLn();
423    Print("entering%-*.*s %s (level %d)\n",myynest*2,myynest*2," ",IDID(pn),myynest);
424  }
425#ifdef RDEBUG
426  if (traceit&TRACE_SHOW_RINGS) iiShowLevRings();
427#endif
428  switch (pi->language)
429  {
430      default:
431      case LANG_NONE:
432                 err=TRUE;
433                 break;
434
435    case LANG_SINGULAR:
436                 #ifdef HAVE_NS
437                 if ((pi->pack!=NULL)&&(currPack!=pi->pack))
438                 {
439                   currPack=pi->pack;
440                   iiCheckPack(currPack);
441                   currPackHdl=packFindHdl(currPack);
442                   //Print("set pack=%s\n",IDID(currPackHdl));
443                 }
444                 else if ((pack!=NULL)&&(currPack!=pack))
445                 {
446                   currPack=pack;
447                   iiCheckPack(currPack);
448                   currPackHdl=packFindHdl(currPack);
449                   //Print("set pack=%s\n",IDID(currPackHdl));
450                 }
451                 #endif
452                 err=iiPStart(pn,sl);
453                 #ifdef HAVE_NS
454                 #endif
455                 break;
456    case LANG_C:
457                 leftv res = (leftv)omAlloc0Bin(sleftv_bin);
458                 err = (pi->data.o.function)(res, sl);
459                 iiRETURNEXPR[myynest+1].Copy(res);
460                 omFreeBin((ADDRESS)res,  sleftv_bin);
461                 break;
462  }
463  if ((traceit&TRACE_SHOW_PROC)
464  || (pi->trace_flag&TRACE_SHOW_PROC))
465  {
466    if (traceit&TRACE_SHOW_LINENO) PrintLn();
467    Print("leaving %-*.*s %s (level %d)\n",myynest*2,myynest*2," ",IDID(pn),myynest);
468  }
469#ifdef RDEBUG
470  if (traceit&TRACE_SHOW_RINGS) iiShowLevRings();
471#endif
472  if (err)
473  {
474    iiRETURNEXPR[myynest+1].CleanUp();
475    //iiRETURNEXPR[myynest+1].Init(); //done by CleanUp
476  }
477#ifdef USE_IILOCALRING
478#if 0
479  if(procstack->cRing != iiLocalRing[myynest]) Print("iiMake_proc: 1 ring not saved procs:%x, iiLocal:%x\n",procstack->cRing, iiLocalRing[myynest]);
480#endif
481  if (iiLocalRing[myynest] != currRing)
482  {
483    if (((iiRETURNEXPR[myynest+1].Typ()>BEGIN_RING)
484      && (iiRETURNEXPR[myynest+1].Typ()<END_RING))
485    || ((iiRETURNEXPR[myynest+1].Typ()==LIST_CMD)
486      && (lRingDependend((lists)iiRETURNEXPR[myynest+1].Data()))))
487    {
488      //idhdl hn;
489      char *n;
490      char *o;
491      if (iiLocalRing[myynest]!=NULL) o=rFindHdl(iiLocalRing[myynest],NULL, NULL)->id;
492      else                            o="none";
493      if (currRing!=NULL)             n=rFindHdl(currRing,NULL, NULL)->id;
494      else                            n="none";
495      Werror("ring change during procedure call: %s -> %s",o,n);
496      iiRETURNEXPR[myynest+1].CleanUp();
497      err=TRUE;
498    }
499    currRing=iiLocalRing[myynest];
500  }
501  if ((currRing!=NULL) &&
502    ((currRingHdl==NULL)||(IDRING(currRingHdl)!=currRing)
503     ||(IDLEV(currRingHdl)>=myynest)))
504  {
505    rSetHdl(rFindHdl(currRing,NULL, NULL));
506    iiLocalRing[myynest]=NULL;
507  }
508#else /* USE_IILOCALRING */
509  if (procstack->cRing != currRing)
510  {
511    //if (procstack->cRingHdl!=NULL)
512    //Print("procstack:%s,",IDID(procstack->cRingHdl));
513    //if (currRingHdl!=NULL)
514    //Print(" curr:%s\n",IDID(currRingHdl));
515    //Print("pr:%x, curr: %x\n",procstack->cRing,currRing);
516    if (((iiRETURNEXPR[myynest+1].Typ()>BEGIN_RING)
517      && (iiRETURNEXPR[myynest+1].Typ()<END_RING))
518    || ((iiRETURNEXPR[myynest+1].Typ()==LIST_CMD)
519      && (lRingDependend((lists)iiRETURNEXPR[myynest+1].Data()))))
520    {
521      //idhdl hn;
522      char *n;
523      char *o;
524      if (procstack->cRing!=NULL)
525      {
526        //PrintS("reset ring\n");
527        procstack->cRingHdl=rFindHdl(procstack->cRing,NULL, NULL);
528        #ifdef HAVE_NS
529        if (procstack->cRingHdl==NULL)
530          procstack->cRingHdl=
531           rFindHdl(procstack->cRing,NULL,procstack->currPack->idroot);
532        if (procstack->cRingHdl==NULL)
533          procstack->cRingHdl=
534           rFindHdl(procstack->cRing,NULL,basePack->idroot);
535        #endif
536        o=IDID(procstack->cRingHdl);
537        currRing=procstack->cRing;
538        currRingHdl=procstack->cRingHdl;
539      }
540      else                            o="none";
541      if (currRing!=NULL)             n=IDID(currRingHdl);
542      else                            n="none";
543      if (currRing==NULL)
544      {
545        Werror("ring change during procedure call: %s -> %s",o,n);
546        iiRETURNEXPR[myynest+1].CleanUp();
547        err=TRUE;
548      }
549    }
550    if (procstack->cRingHdl!=NULL)
551    {
552      rSetHdl(procstack->cRingHdl);
553    }
554    else
555    { currRingHdl=NULL; currRing=NULL; }
556  }
557#endif /* USE_IILOCALRING */
558  if (iiCurrArgs!=NULL)
559  {
560    if (!err) Warn("too many arguments for %s",IDID(pn));
561    iiCurrArgs->CleanUp();
562    omFreeBin((ADDRESS)iiCurrArgs, sleftv_bin);
563    iiCurrArgs=NULL;
564  }
565  procstack->pop();
566  if (err)
567    return NULL;
568  return &iiRETURNEXPR[myynest+1];
569}
570
571/*2
572* start an example (as a proc),
573* destroys the string 'example'
574*/
575BOOLEAN iiEStart(char* example, procinfo *pi)
576{
577  BOOLEAN err;
578  int old_echo=si_echo;
579
580  newBuffer( example, BT_example, pi,
581             (pi != NULL ? pi->data.s.example_lineno: 0));
582
583  iiCheckNest();
584  procstack->push(example);
585#ifdef USE_IILOCALRING
586  iiLocalRing[myynest]=currRing;
587#endif
588  if (traceit&TRACE_SHOW_PROC)
589  {
590    if (traceit&TRACE_SHOW_LINENO) printf("\n");
591    printf("entering example (level %d)\n",myynest);
592  }
593  myynest++;
594  err=yyparse();
595  if (sLastPrinted.rtyp!=0)
596  {
597    sLastPrinted.CleanUp();
598    //memset(&sLastPrinted,0,sizeof(sleftv)); //done by CleanUp
599  }
600  killlocals(myynest);
601  myynest--;
602  si_echo=old_echo;
603  if (traceit&TRACE_SHOW_PROC)
604  {
605    if (traceit&TRACE_SHOW_LINENO) printf("\n");
606    printf("leaving  -example- (level %d)\n",myynest);
607  }
608#ifdef USE_IILOCALRING
609  if (iiLocalRing[myynest] != currRing)
610  {
611    if (iiLocalRing[myynest]!=NULL)
612    {
613      rSetHdl(rFindHdl(iiLocalRing[myynest],NULL, NULL));
614      iiLocalRing[myynest]=NULL;
615    }
616    else
617    {
618      currRingHdl=NULL;
619      currRing=NULL;
620    }
621  }
622#else /* USE_IILOCALRING */
623#endif /* USE_IILOCALRING */
624  if (NS_LRING != currRing)
625  {
626    if (NS_LRING!=NULL)
627    {
628      idhdl rh=procstack->cRingHdl;
629      if ((rh==NULL)||(IDRING(rh)!=NS_LRING))
630        rh=rFindHdl(NS_LRING,NULL, NULL);
631      rSetHdl(rh);
632    }
633    else
634    {
635      currRingHdl=NULL;
636      currRing=NULL;
637    }
638  }
639//#endif /* USE_IILOCALRING */
640  procstack->pop();
641  return err;
642}
643
644/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
645static BOOLEAN iiLoadLIB(FILE *fp, char *libnamebuf, char *newlib,
646                         idhdl pl, BOOLEAN autoexport, BOOLEAN tellerror);
647
648BOOLEAN iiTryLoadLib(leftv v, char *id)
649{
650  BOOLEAN LoadResult = TRUE;
651#ifdef HAVE_NAMESPACES
652  char libnamebuf[128];
653  char *libname = (char *)omAlloc(strlen(id)+5);
654  char *suffix[] = { "", ".lib", ".so", ".sl", NULL };
655  int i = 0;
656  FILE *fp;
657  package pack;
658  idhdl packhdl;
659  lib_types LT;
660
661  for(i=0; suffix[i] != NULL; i++)
662  {
663    sprintf(libname, "%s%s", id, suffix[i]);
664    *libname = mytolower(*libname);
665    if((LT = type_of_LIB(libname, libnamebuf)) > LT_NOTFOUND)
666    {
667      char *s=omStrDup(libname);
668      char libnamebuf[256];
669
670      if (LT==LT_SINGULAR)
671        LoadResult = iiLibCmd(s, FALSE);
672      else if ((LT==LT_ELF) || (LT==LT_HPUX))
673        LoadResult = load_modules(s,libnamebuf,FALSE);
674      if(!LoadResult )
675      {
676        v->name = iiConvName(libname);
677        break;
678      }
679    }
680  }
681  omFree(libname);
682#else /* HAVE_NAMESPACES */
683#endif /* HAVE_NAMESPACES */
684  return LoadResult;
685}
686
687BOOLEAN iiReLoadLib(idhdl packhdl)
688{
689  BOOLEAN LoadResult = TRUE;
690#ifdef HAVE_NAMESPACES
691  char libnamebuf[128];
692  package pack = IDPACKAGE(packhdl);
693
694  if(pack->language == LANG_NONE) return FALSE;
695
696  FILE * fp = feFopen( pack->libname, "r", libnamebuf, FALSE);
697  if (fp==NULL)
698  {
699    return TRUE;
700  }
701  namespaceroot->push(IDPACKAGE(packhdl), IDID(packhdl));
702  LoadResult = iiLoadLIB(fp, libnamebuf, IDPACKAGE(packhdl)->libname,
703                         packhdl, FALSE, FALSE);
704  namespaceroot->pop();
705#else /* HAVE_NAMESPACES */
706#endif /* HAVE_NAMESPACES */
707  return LoadResult;
708}
709
710/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
711/* check, if library lib has already been loaded
712   if yes, writes filename of lib into where and returns TRUE,
713      no, returns FALSE
714*/
715BOOLEAN iiLocateLib(const char* lib, char* where)
716{
717  idhdl hl;
718
719  char *p;
720
721  hl = IDROOT->get("LIB", 0);
722  if (hl == NULL || (p=strstr(IDSTRING(hl), lib)) == NULL) return FALSE;
723  if ((p!=IDSTRING(hl)) && (*(p-1)!=',')) return FALSE;
724
725  if (strstr(IDSTRING(hl), ",") == NULL)
726  {
727    strcpy(where, IDSTRING(hl));
728  }
729  else
730  {
731    char* tmp = omStrDup(IDSTRING(hl));
732    char* tok = strtok(tmp, ",");
733    do
734    {
735      if (strstr(tok, lib) != NULL) break;
736      tok = strtok(NULL, ",");
737    }
738    while (tok != NULL);
739    assume(tok != NULL);
740    strcpy(where, tok);
741    omFree(tmp);
742  }
743  return TRUE;
744}
745
746BOOLEAN iiLibCmd( char *newlib, BOOLEAN tellerror )
747{
748  char buf[256];
749  char libnamebuf[128];
750  idhdl h;
751  BOOLEAN LoadResult = TRUE;
752#ifdef HAVE_NS
753  idhdl pl;
754#endif
755  idhdl hl;
756  int lines = 1;
757  long pos = 0L;
758  procinfov pi;
759#ifdef HAVE_NS
760  char *plib = iiConvName(newlib);
761#endif
762  FILE * fp = feFopen( newlib, "r", libnamebuf, tellerror );
763  if (fp==NULL)
764  {
765    return TRUE;
766  }
767#ifndef HAVE_NS
768  hl = idroot->get("LIB",0);
769  if (hl==NULL)
770  {
771    hl = enterid( "LIB",0, STRING_CMD, &idroot, FALSE );
772    IDSTRING(hl) = omStrDup(newlib);
773  }
774  else
775  {
776#ifdef TEST
777    if (IDSTRING(hl) != NULL)
778#endif
779    {
780      char *s = (char *)omAlloc( strlen(newlib) + strlen(IDSTRING(hl)) + 2 );
781      strcpy(s,IDSTRING(hl));
782      BOOLEAN f=FALSE;
783      if(strchr(s,',')==NULL)
784      {
785        if (strcmp(s,newlib)==0)
786          f=TRUE;
787      }
788      else
789      {
790        char *p=strtok(s,",");
791        do
792        {
793          if(strcmp(p,newlib)==0)
794          {
795            f=TRUE;
796            break;
797          }
798          p=strtok(NULL,",");
799        } while (p!=NULL);
800      }
801      if (f)
802        omFree((ADDRESS)s);
803      else
804      {
805        sprintf( s, "%s,%s", IDSTRING(hl), newlib);
806        omFree((ADDRESS)IDSTRING(hl));
807        IDSTRING(hl) = s;
808      }
809    }
810#ifdef TEST
811    else
812    {
813      PrintS("## empty LIB string\n");
814      IDSTRING(hl) = omStrDup(newlib);
815    }
816#endif
817  }
818#endif /* HAVE_NS */
819#ifdef HAVE_TCL
820  if (tclmode)
821  {
822    PrintTCLS('L',newlib);
823  }
824#endif
825#ifdef HAVE_NS
826  pl = basePack->idroot->get(plib,0);
827  if (pl==NULL)
828  {
829    pl = enterid( plib,0, PACKAGE_CMD,
830                  &(basePack->idroot), TRUE );
831    IDPACKAGE(pl)->language = LANG_SINGULAR;
832    IDPACKAGE(pl)->libname=omStrDup(newlib);
833  }
834  else
835  {
836    if(IDTYP(pl)!=PACKAGE_CMD)
837    {
838      WarnS("not of typ package.");
839      fclose(fp);
840      return TRUE;
841    }
842  }
843  LoadResult = iiLoadLIB(fp, libnamebuf, newlib, pl, TRUE, tellerror);
844#else /* HAVE_NS */
845  LoadResult = iiLoadLIB(fp, libnamebuf, newlib, NULL, FALSE, tellerror);
846#endif /* HAVE_NS */
847
848  omFree((ADDRESS)newlib);
849
850#ifdef HAVE_NS
851  if(!LoadResult) IDPACKAGE(pl)->loaded = TRUE;
852  omFree((ADDRESS)plib);
853#endif /* HAVE_NS */
854
855 return LoadResult;
856}
857
858/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
859static void iiCleanProcs(idhdl &root)
860{
861  idhdl prev=NULL;
862  loop
863  {
864    if (root==NULL) return;
865    if (IDTYP(root)==PROC_CMD)
866    {
867      procinfo *pi=(procinfo*)IDDATA(root);
868      if ((pi->language == LANG_SINGULAR)
869      && (pi->data.s.body_start == 0L))
870      {
871        // procinfo data incorrect:
872        // - no proc body can start at the beginning of the file
873        killhdl(root);
874        if (prev==NULL)
875          root=IDROOT;
876        else
877        {
878          root=prev;
879          prev=NULL;
880        }
881        continue;
882      }
883    }
884    prev=root;
885    root=IDNEXT(root);
886  }
887}
888/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
889static BOOLEAN iiLoadLIB(FILE *fp, char *libnamebuf, char*newlib,
890             idhdl pl, BOOLEAN autoexport, BOOLEAN tellerror)
891{
892  char buf[256];
893  extern FILE *yylpin;
894  libstackv ls_start = library_stack;
895  lib_style_types lib_style;
896
897  yylpin = fp;
898  #if YYLPDEBUG > 1
899  print_init();
900  #endif
901  extern int lpverbose;
902  if (BVERBOSE(V_DEBUG_LIB)) lpverbose=1;
903  else lpverbose=0;
904  #ifdef HAVE_NS
905    yylplex(newlib, libnamebuf, &lib_style, pl, autoexport);
906  #else
907    yylplex(newlib, libnamebuf, &lib_style);
908  #endif /* HAVE_NS */
909  if(yylp_errno)
910  {
911    Werror("Library %s: ERROR occured: in line %d, %d.", newlib, yylplineno,
912         current_pos(0));
913    if(yylp_errno==YYLP_BAD_CHAR)
914    {
915      Werror(yylp_errlist[yylp_errno], *text_buffer, yylplineno);
916      omFree((ADDRESS)text_buffer);
917      text_buffer=NULL;
918    }
919    else
920      Werror(yylp_errlist[yylp_errno], yylplineno);
921    Werror("Cannot load library,... aborting.");
922    reinit_yylp();
923    fclose( yylpin );
924    iiCleanProcs(IDROOT);
925    return TRUE;
926  }
927  if (BVERBOSE(V_LOAD_LIB))
928    Print( "// ** loaded %s %s\n", libnamebuf, text_buffer);
929  if( (lib_style == OLD_LIBSTYLE) && (BVERBOSE(V_LOAD_LIB)))
930  {
931    Warn( "library %s has old format. This format is still accepted,", newlib);
932    Warn( "but for functionality you may wish to change to the new");
933    Warn( "format. Please refer to the manual for further information.");
934  }
935  reinit_yylp();
936  fclose( yylpin );
937  fp = NULL;
938
939  {
940    libstackv ls;
941    for(ls = library_stack; (ls != NULL) && (ls != ls_start); )
942    {
943      if(ls->to_be_done)
944      {
945        ls->to_be_done=FALSE;
946        iiLibCmd(ls->get());
947        ls = ls->pop(newlib);
948      }
949    }
950#if 0
951    PrintS("--------------------\n");
952    for(ls = library_stack; ls != NULL; ls = ls->next)
953    {
954      Print("%s: LIB-stack:(%d), %s %s\n", newlib, ls->cnt, ls->get(),
955        ls->to_be_done ? "not loaded" : "loaded");
956    }
957    PrintS("--------------------\n");
958#endif
959  }
960
961  if(fp != NULL) fclose(fp);
962  return FALSE;
963}
964
965
966/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
967procinfo *iiInitSingularProcinfo(procinfov pi, char *libname, char *procname,
968                                 int line, long pos, BOOLEAN pstatic)
969{
970  pi->libname = omStrDup(libname);
971
972  if( strcmp(procname,"_init")==0)
973  {
974    pi->procname = iiConvName(libname);
975  }
976  else
977    pi->procname = omStrDup(procname);
978  pi->language = LANG_SINGULAR;
979  pi->ref = 1;
980#ifdef HAVE_NS
981  pi->pack = NULL;
982#endif
983  pi->is_static = pstatic;
984  pi->data.s.proc_start = pos;
985  pi->data.s.def_end    = 0L;
986  pi->data.s.help_start = 0L;
987  pi->data.s.help_end   = 0L;
988  pi->data.s.body_start = 0L;
989  pi->data.s.body_end   = 0L;
990  pi->data.s.example_start = 0L;
991  pi->data.s.proc_lineno = line;
992  pi->data.s.body_lineno = 0;
993  pi->data.s.example_lineno = 0;
994  pi->data.s.body = NULL;
995  pi->data.s.help_chksum = 0;
996  return(pi);
997}
998
999#ifdef HAVE_DYNAMIC_LOADING
1000/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
1001int iiAddCproc(char *libname, char *procname, BOOLEAN pstatic,
1002               BOOLEAN(*func)(leftv res, leftv v))
1003{
1004  procinfov pi;
1005  idhdl h;
1006
1007  h = enterid(procname,0, PROC_CMD, &IDROOT, TRUE);
1008  if ( h!= NULL )
1009  {
1010    pi = IDPROC(h);
1011    pi->libname = omStrDup(libname);
1012    pi->procname = omStrDup(procname);
1013    pi->language = LANG_C;
1014    pi->ref = 1;
1015    pi->is_static = pstatic;
1016    pi->data.o.function = func;
1017    return(1);
1018  }
1019  else
1020  {
1021    PrintS("iiAddCproc: failed.\n");
1022  }
1023  return(0);
1024}
1025
1026/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
1027BOOLEAN load_modules(char *newlib, char *fullname, BOOLEAN tellerror)
1028{
1029#ifdef HAVE_STATIC
1030  WerrorS("mod_init: static version can not load modules");
1031  return TRUE;
1032#else
1033  int iiAddCproc(char *libname, char *procname, BOOLEAN pstatic,
1034                 BOOLEAN(*func)(leftv res, leftv v));
1035  typedef int (*fktn_t)(int(*iiAddCproc)(char *libname, char *procname,
1036                               BOOLEAN pstatic,
1037                               BOOLEAN(*func)(leftv res, leftv v)));
1038  fktn_t fktn;
1039  idhdl pl;
1040  char *plib = iiConvName(newlib);
1041  BOOLEAN RET=TRUE;
1042  int token;
1043  char FullName[256];
1044
1045  memset(FullName,0,256);
1046
1047  if( *fullname != '/' &&  *fullname != '.' )
1048    sprintf(FullName, "./%s", newlib);
1049  else strncpy(FullName, fullname,255);
1050
1051
1052  if(IsCmd(plib, token))
1053  {
1054    Werror("'%s' is resered identifier\n", plib);
1055    goto load_modules_end;
1056  }
1057  pl = IDROOT->get(plib,0);
1058  if (pl==NULL)
1059  {
1060    pl = enterid( plib,0, PACKAGE_CMD, &IDROOT,
1061                  TRUE );
1062    IDPACKAGE(pl)->language = LANG_C;
1063    IDPACKAGE(pl)->libname=omStrDup(newlib);
1064  }
1065  else
1066  {
1067    if(IDTYP(pl)!=PACKAGE_CMD)
1068    {
1069      Warn("not of typ package.");
1070      goto load_modules_end;
1071    }
1072  }
1073  if((IDPACKAGE(pl)->handle=dynl_open(FullName))==(void *)NULL)
1074  {
1075    Werror("dynl_open failed:%s", dynl_error());
1076    Werror("%s not found", newlib);
1077    goto load_modules_end;
1078  }
1079  else
1080  {
1081#ifdef HAVE_NS
1082    package s=currPack;
1083    currPack=IDPACKAGE(pl);
1084#endif
1085    fktn = (fktn_t)dynl_sym(IDPACKAGE(pl)->handle, "mod_init");
1086    if( fktn!= NULL) (*fktn)(iiAddCproc);
1087    else Werror("mod_init: %s\n", dynl_error());
1088    if (BVERBOSE(V_LOAD_LIB)) Print( "// ** loaded %s \n", fullname);
1089#ifdef HAVE_NS
1090    currPack->loaded=1;
1091    currPack=s;
1092#endif
1093  }
1094  RET=FALSE;
1095
1096  load_modules_end:
1097  return RET;
1098#endif /*STATIC */ 
1099}
1100#endif /* HAVE_DYNAMIC_LOADING */
1101
1102/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
1103char mytoupper(char c)
1104{
1105  if(c>=97 && c<=(97+26)) c-=32;
1106  return(c);
1107}
1108
1109char mytolower(char c)
1110{
1111  if(c>=65 && c<=(65+26)) c+=32;
1112  return(c);
1113}
1114
1115/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
1116//#if defined(WINNT)
1117//#  define  FS_SEP '\\'
1118//#elif defined(macintosh)
1119//#  define FS_SEP ','
1120//#else
1121//#  define FS_SEP '/'
1122//#endif
1123
1124static char *iiConvName(const char *libname)
1125{
1126  char *tmpname = omStrDup(libname);
1127  char *p = strrchr(tmpname, DIR_SEP);
1128  char *r;
1129  if(p==NULL) p = tmpname;
1130  else p++;
1131  r = strchr(p, '.');
1132  if( r!= NULL) *r = '\0';
1133  r = omStrDup(p);
1134  *r = mytoupper(*r);
1135  // printf("iiConvName: '%s' '%s' => '%s'\n", libname, tmpname, r);
1136  omFree((ADDRESS)tmpname);
1137
1138  return(r);
1139}
1140
1141/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
1142void piShowProcList()
1143{
1144  idhdl h;
1145  procinfo *proc;
1146  char *name;
1147
1148  Print( "%-15s  %20s      %s,%s  %s,%s   %s,%s\n", "Library", "function",
1149         "line", "start", "line", "body", "line", "example");
1150  for(h = IDROOT; h != NULL; h = IDNEXT(h))
1151  {
1152    if(IDTYP(h) == PROC_CMD)
1153    {
1154      proc = IDPROC(h);
1155      if(strcmp(proc->procname, IDID(h))!=0)
1156      {
1157        name = (char *)omAlloc(strlen(IDID(h))+strlen(proc->procname)+4);
1158        sprintf(name, "%s -> %s", IDID(h), proc->procname);
1159        Print( "%d %-15s  %20s ", proc->is_static ? 1 : 0, proc->libname, name);
1160        omFree((ADDRESS)name);
1161      }
1162      else
1163        Print( "%d %-15s  %20s ", proc->is_static ? 1 : 0, proc->libname,
1164               proc->procname);
1165      if(proc->language==LANG_SINGULAR)
1166        Print("line %4d,%-5ld  %4d,%-5ld  %4d,%-5ld\n",
1167              proc->data.s.proc_lineno, proc->data.s.proc_start,
1168              proc->data.s.body_lineno, proc->data.s.body_start,
1169              proc->data.s.example_lineno, proc->data.s.example_start);
1170      else if(proc->language==LANG_C)
1171        Print("type: object\n");
1172    }
1173  }
1174}
1175
1176/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
1177//char *iiLineNo(char *procname, int lineno)
1178//{
1179//  char buf[256];
1180//  idhdl pn = ggetid(procname);
1181//  procinfo *pi = IDPROC(pn);
1182//
1183//  sprintf(buf, "%s %3d\0", procname, lineno);
1184//  //sprintf(buf, "%s::%s %3d\0", pi->libname, pi->procname,
1185//  //  lineno + pi->data.s.body_lineno);
1186//  return(buf);
1187//}
1188/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
1189#ifdef HAVE_LIBPARSER
1190void libstack::push(char *p, char *libname)
1191{
1192  libstackv lp;
1193  if( !iiGetLibStatus(libname))
1194  {
1195    for(lp = this;lp!=NULL;lp=lp->next)
1196    {
1197      if(strcmp(lp->get(), libname)==0) break;
1198    }
1199    if(lp==NULL)
1200    {
1201      libstackv ls = (libstack *)omAlloc0Bin(libstack_bin);
1202      ls->next = this;
1203      ls->libname = omStrDup(libname);
1204      ls->to_be_done = TRUE;
1205      if(this != NULL) ls->cnt = this->cnt+1; else ls->cnt = 0;
1206      library_stack = ls;
1207    }
1208  }
1209}
1210
1211libstackv libstack::pop(char *p)
1212{
1213  libstackv ls = this;
1214  //omFree((ADDRESS)ls->libname);
1215  library_stack = ls->next;
1216  omFreeBin((ADDRESS)ls,  libstack_bin);
1217  return(library_stack);
1218}
1219
1220#endif /* HAVE_LIBPARSER */
1221/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
1222#ifndef HOWMANY
1223# define HOWMANY 8192           /* how much of the file to look at */
1224#endif
1225
1226lib_types type_of_LIB(char *newlib, char *libnamebuf)
1227{
1228  char        buf[HOWMANY+1];        /* one extra for terminating '\0' */
1229  struct stat sb;
1230  int nbytes = 0;
1231  int ret;
1232  lib_types LT=LT_NONE;
1233
1234  FILE * fp = feFopen( newlib, "r", libnamebuf, FALSE );
1235  ret = stat(libnamebuf, &sb);
1236
1237  if (fp==NULL)
1238  {
1239    return LT_NOTFOUND;
1240  }
1241  if((sb.st_mode & S_IFMT) != S_IFREG)
1242  {
1243    goto lib_type_end;
1244  }
1245  if ((nbytes = fread((char *)buf, sizeof(char), HOWMANY, fp)) == -1)
1246  {
1247    goto lib_type_end;
1248    /*NOTREACHED*/
1249  }
1250  if (nbytes == 0)
1251    goto lib_type_end;
1252  else
1253  {
1254    buf[nbytes++] = '\0';        /* null-terminate it */
1255  }
1256  if( (strncmp(buf, "\177ELF\01\01\01", 7)==0) && buf[16]=='\03')
1257  {
1258    LT = LT_ELF;
1259    //omFree(newlib);
1260    //newlib = omStrDup(libnamebuf);
1261    goto lib_type_end;
1262  }
1263  if( (strncmp(buf, "\02\020\01\016\05\022@", 7)==0))
1264  {
1265    LT = LT_HPUX;
1266    //omFree(newlib);
1267    //newlib = omStrDup(libnamebuf);
1268    goto lib_type_end;
1269  }
1270  if(isprint(buf[0]) || buf[0]=='\n')
1271  { LT = LT_SINGULAR; goto lib_type_end; }
1272
1273  lib_type_end:
1274  fclose(fp);
1275  return LT;
1276}
1277/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
Note: See TracBrowser for help on using the repository browser.