source: git/Singular/ipid.cc @ 8d8cd94

spielwiese
Last change on this file since 8d8cd94 was 8d8cd94, checked in by Hans Schoenemann <hannes@…>, 12 years ago
fix: return value of enterid for packages
  • Property mode set to 100644
File size: 15.2 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: identfier handling
6*/
7
8#include <string.h>
9
10#include "config.h"
11#include <kernel/mod2.h>
12#include <Singular/static.h>
13#include <omalloc/omalloc.h>
14#include <Singular/tok.h>
15#include <misc/options.h>
16#include <Singular/ipshell.h>
17#include <misc/intvec.h>
18#include <kernel/febase.h>
19#include <coeffs/numbers.h>
20#include <kernel/longrat.h>
21#include <kernel/polys.h>
22#include <polys/monomials/ring.h>
23#include <kernel/ideals.h>
24#include <polys/matpol.h>
25#include <Singular/lists.h>
26#include <Singular/attrib.h>
27#include <Singular/silink.h>
28#include <kernel/syz.h>
29#include <Singular/ipid.h>
30#include <Singular/blackbox.h>
31
32#ifdef HAVE_DYNAMIC_LOADING
33#include <polys/mod_raw.h>
34#endif /* HAVE_DYNAMIC_LOADING */
35
36omBin sip_command_bin = omGetSpecBin(sizeof(sip_command));
37omBin sip_package_bin = omGetSpecBin(sizeof(sip_package));
38//omBin ip_package_bin = omGetSpecBin(sizeof(ip_package));
39omBin idrec_bin = omGetSpecBin(sizeof(idrec));
40
41coeffs coeffs_BIGINT;
42
43FILE   *feFilePending; /*temp. storage for grammar.y */
44
45proclevel *procstack=NULL;
46#define TEST
47//idhdl idroot = NULL;
48
49idhdl currPackHdl = NULL;
50idhdl basePackHdl = NULL;
51package currPack =NULL;
52package basePack =NULL;
53idhdl currRingHdl = NULL;
54const char* iiNoName="_";
55
56void paCleanUp(package pack);
57
58/*0 implementation*/
59
60int iiS2I(const char *s)
61{
62  int i;
63  i=s[0];
64  if (s[1]!='\0')
65  {
66    i=(i<<8)+s[1];
67    if (s[2]!='\0')
68    {
69      i=(i<<8)+s[2];
70      if (s[3]!='\0')
71      {
72        i=(i<<8)+s[3];
73      }
74    }
75  }
76  return i;
77}
78
79idhdl idrec::get(const char * s, int level)
80{
81  assume(s!=NULL);
82  assume((level>=0) && (level<=1000)); //not really, but if it isnt in that bounds..
83  idhdl h = this;
84  idhdl found=NULL;
85  int l;
86  const char *id_;
87  int i=iiS2I(s);
88  int less4=(i < (1<<24));
89  while (h!=NULL)
90  {
91    omCheckAddr((ADDRESS)IDID(h));
92    l=IDLEV(h);
93    if ((l==0)||(l==level))
94    {
95      if (i==h->id_i)
96      {
97        id_=IDID(h);
98        if (less4 || (0 == strcmp(s+4,id_+4)))
99        {
100          if (l==level) return h;
101          found=h;
102        }
103      }
104    }
105    h = IDNEXT(h);
106  }
107  return found;
108}
109
110//idrec::~idrec()
111//{
112//  if (id!=NULL)
113//  {
114//    omFree((ADDRESS)id);
115//    id=NULL;
116//  }
117//  /* much more !! */
118//}
119
120void *idrecDataInit(int t)
121{
122  switch (t)
123  {
124    //the type with init routines:
125    case INTVEC_CMD:
126    case INTMAT_CMD:
127      return (void *)new intvec();
128    case NUMBER_CMD:
129      return (void *) nInit(0);
130    case BIGINT_CMD:
131      return (void *) n_Init(0, coeffs_BIGINT);
132    case IDEAL_CMD:
133    case MODUL_CMD:
134    case MATRIX_CMD:
135      return (void*) idInit(1,1);
136    case MAP_CMD:
137    {
138      map m = (map)idInit(1,1);
139      m->preimage = omStrDup(IDID(currRingHdl));
140      return (void *)m;
141    }
142    case STRING_CMD:
143      return (void *)omAlloc0(1);
144    case LIST_CMD:
145    {
146      lists l=(lists)omAllocBin(slists_bin);
147      l->Init();
148      return (void*)l;
149    }
150    //the types with the standard init: set the struct to zero
151    case LINK_CMD:
152      return (void*) omAlloc0Bin(sip_link_bin);
153    case RING_CMD:
154      return (void*) omAlloc0Bin(sip_sring_bin);
155    case PACKAGE_CMD:
156      return (void*) omAlloc0Bin(sip_package_bin);
157    case PROC_CMD:
158      return (void *) omAlloc0Bin(procinfo_bin);
159    case RESOLUTION_CMD:
160      return  (void *)omAlloc0(sizeof(ssyStrategy));
161    //other types: without init (int,script,poly,def,package)
162    case INT_CMD:
163    case DEF_CMD:
164    case POLY_CMD:
165    case VECTOR_CMD:
166    case QRING_CMD:
167       return (void*)0L;
168    default:
169      {
170        if (t>MAX_TOK)
171        {
172#ifdef BLACKBOX_DEVEL
173          Print("bb-type %d\n",t);
174#endif
175          blackbox *bb=getBlackboxStuff(t);
176          if (bb!=NULL)
177             return (void *)bb->blackbox_Init(bb);
178        }
179        else
180          Werror("unknown type %d",t);
181        break;
182      }
183  }
184  return (void *)0L;
185}
186idhdl idrec::set(const char * s, int level, int t, BOOLEAN init)
187{
188  //printf("define %s, %x, level: %d, typ: %d\n", s,s,level,t);
189  idhdl h = (idrec *)omAlloc0Bin(idrec_bin);
190  IDID(h)   = s;
191  IDTYP(h)  = t;
192  IDLEV(h)  = level;
193  IDNEXT(h) = this;
194  h->id_i=iiS2I(s);
195  if (init)
196  {
197    if ((t==IDEAL_CMD)||(t==MODUL_CMD))
198      IDFLAG(h) = Sy_bit(FLAG_STD);
199    IDSTRING(h)=(char *)idrecDataInit(t);
200    // additional settings:--------------------------------------
201#if 0
202    // this leads to a memory leak
203    if (t == QRING_CMD)
204    {
205      // IDRING(h)=rCopy(currRing);
206      /* QRING_CMD is ring dep => currRing !=NULL */
207    }
208    else
209#endif
210    if (t == PROC_CMD)
211    {
212      IDPROC(h)->language=LANG_NONE;
213    }
214    else if (t == PACKAGE_CMD)
215    {
216      IDPACKAGE(h)->language=LANG_NONE;
217      IDPACKAGE(h)->loaded = FALSE;
218    }
219  }
220  // --------------------------------------------------------
221  return  h;
222}
223
224char * idrec::String(BOOLEAN typed)
225{
226  sleftv tmp;
227  memset(&tmp,0,sizeof(sleftv));
228  tmp.rtyp=IDTYP(this);
229  tmp.data=IDDATA(this);
230  tmp.name=IDID(this);
231  return tmp.String(NULL, typed);
232}
233
234idhdl enterid(const char * s, int lev, int t, idhdl* root, BOOLEAN init, BOOLEAN search)
235{
236  if (s==NULL) return NULL;
237  idhdl h;
238  s=omStrDup(s);
239  idhdl *save_root=root;
240  if (t==PACKAGE_CMD)
241  {
242    if (root!=&(basePack->idroot))
243    {
244      root=&(basePack->idroot);
245    }
246  }
247  // is it already defined in root ?
248  if ((h=(*root)->get(s,lev))!=NULL)
249  {
250    if (IDLEV(h)==lev)
251    {
252      if ((IDTYP(h) == t)||(t==DEF_CMD))
253      {
254        if ((IDTYP(h)==PACKAGE_CMD)
255        && (strcmp(s,"Top")==0))
256        {
257          goto errlabel;
258        }
259        if (BVERBOSE(V_REDEFINE))
260          Warn("redefining %s **",s);
261        if (s==IDID(h)) IDID(h)=NULL;
262        killhdl2(h,root,currRing);
263      }
264      else
265        goto errlabel;
266    }
267  }
268  // is it already defined in currRing->idroot ?
269  else if (search && (currRing!=NULL)&&((*root) != currRing->idroot))
270  {
271    if ((h=currRing->idroot->get(s,lev))!=NULL)
272    {
273      if (IDLEV(h)==lev)
274      {
275        if ((IDTYP(h) == t)||(t==DEF_CMD))
276        {
277          if (BVERBOSE(V_REDEFINE))
278            Warn("redefining %s **",s);
279          IDID(h)=NULL;
280          killhdl2(h,&currRing->idroot,currRing);
281        }
282        else
283          goto errlabel;
284      }
285    }
286  }
287  // is it already defined in idroot ?
288  else if (search && (*root != IDROOT))
289  {
290    if ((h=IDROOT->get(s,lev))!=NULL)
291    {
292      if (IDLEV(h)==lev)
293      {
294        if ((IDTYP(h) == t)||(t==DEF_CMD))
295        {
296          if (BVERBOSE(V_REDEFINE))
297            Warn("redefining `%s` **",s);
298          if (s==IDID(h)) IDID(h)=NULL;
299          killhdl2(h,&IDROOT,NULL);
300        }
301        else
302          goto errlabel;
303      }
304    }
305  }
306  *root = (*root)->set(s, lev, t, init);
307#ifndef NDEBUG
308  checkall();
309#endif
310  return *root;
311
312  errlabel:
313    //Werror("identifier `%s` in use(lev h=%d,typ=%d,t=%d, curr=%d)",s,IDLEV(h),IDTYP(h),t,lev);
314    Werror("identifier `%s` in use",s);
315    //listall();
316    omFree((ADDRESS)s);
317    return NULL;
318}
319void killid(const char * id, idhdl * ih)
320{
321  if (id!=NULL)
322  {
323    idhdl h = (*ih)->get(id,myynest);
324
325    // id not found in global list, is it defined in current ring ?
326    if (h==NULL)
327    {
328      if ((currRing!=NULL) && (*ih != (currRing->idroot)))
329      {
330        h = currRing->idroot->get(id,myynest);
331        if (h!=NULL)
332        {
333          killhdl2(h,&(currRing->idroot),currRing);
334          return;
335        }
336      }
337      Werror("`%s` is not defined",id);
338      return;
339    }
340    killhdl2(h,ih,currRing);
341  }
342  else
343    Werror("kill what ?");
344}
345
346void killhdl(idhdl h, package proot)
347{
348  int t=IDTYP(h);
349  if (((BEGIN_RING<t) && (t<END_RING) && (t!=QRING_CMD))
350  || ((t==LIST_CMD) && (lRingDependend((lists)IDDATA(h)))))
351    killhdl2(h,&currRing->idroot,currRing);
352  else
353  {
354    if(t==PACKAGE_CMD)
355    {
356      killhdl2(h,&(basePack->idroot),NULL);
357    }
358    else
359    {
360      idhdl s=proot->idroot;
361      while ((s!=h) && (s!=NULL)) s=s->next;
362      if (s!=NULL)
363        killhdl2(h,&(proot->idroot),NULL);
364      else if (basePack!=proot)
365      {
366        idhdl s=basePack->idroot;
367        while ((s!=h) && (s!=NULL)) s=s->next;
368        if (s!=NULL)
369          killhdl2(h,&(basePack->idroot),currRing);
370        else
371          killhdl2(h,&(currRing->idroot),currRing);
372       }
373    }
374  }
375}
376
377void killhdl2(idhdl h, idhdl * ih, ring r)
378{
379  //printf("kill %s, id %x, typ %d lev: %d\n",IDID(h),(int)IDID(h),IDTYP(h),IDLEV(h));
380  idhdl hh;
381
382  if (h->attribute!=NULL)
383  {
384    //h->attribute->killAll(r); MEMORY LEAK!
385    h->attribute=NULL;
386  }
387  if (IDTYP(h) == PACKAGE_CMD)
388  {
389    if (strcmp(IDID(h),"Top")==0)
390    {
391      WarnS("can not kill `Top`");
392      return;
393    }
394    // any objects defined for this package ?
395    if ((IDPACKAGE(h)->ref<=0)  &&  (IDPACKAGE(h)->idroot!=NULL))
396    {
397      if (currPack==IDPACKAGE(h))
398      {
399        currPack=basePack;
400        currPackHdl=NULL;
401      }
402      idhdl * hd = &IDRING(h)->idroot;
403      idhdl  hdh = IDNEXT(*hd);
404      idhdl  temp;
405      while (hdh!=NULL)
406      {
407        temp = IDNEXT(hdh);
408        killhdl2(hdh,&(IDPACKAGE(h)->idroot),NULL);
409        hdh = temp;
410      }
411      killhdl2(*hd,hd,NULL);
412      if (IDPACKAGE(h)->libname!=NULL) omFree((ADDRESS)(IDPACKAGE(h)->libname));
413    }
414    paKill(IDPACKAGE(h));
415    if (currPackHdl==h) currPackHdl=packFindHdl(currPack);
416    iiCheckPack(currPack);
417  }
418  else if ((IDTYP(h)==RING_CMD)||(IDTYP(h)==QRING_CMD))
419    rKill(h);
420  else
421    s_internalDelete(IDTYP(h),IDDATA(h),r);
422  //  general  -------------------------------------------------------------
423  // now dechain it and delete idrec
424  if (IDID(h)!=NULL) // OB: ?????
425    omFree((ADDRESS)IDID(h));
426  IDID(h)=NULL;
427  IDDATA(h)=NULL;
428  if (h == (*ih))
429  {
430    // h is at the beginning of the list
431    *ih = IDNEXT(h) /* ==*ih */;
432  }
433  else if (ih!=NULL)
434  {
435    // h is somethere in the list:
436    hh = *ih;
437    loop
438    {
439      if (hh==NULL)
440      {
441        PrintS(">>?<< not found for kill\n");
442        return;
443      }
444      idhdl hhh = IDNEXT(hh);
445      if (hhh == h)
446      {
447        IDNEXT(hh) = IDNEXT(hhh);
448        break;
449      }
450      hh = hhh;
451    }
452  }
453  omFreeBin((ADDRESS)h, idrec_bin);
454}
455
456idhdl ggetid(const char *n, BOOLEAN local, idhdl *packhdl)
457{
458  idhdl h = IDROOT->get(n,myynest);
459  idhdl h2=NULL;
460  *packhdl = NULL;
461  if ((currRing!=NULL) && ((h==NULL)||(IDLEV(h)!=myynest)))
462  {
463    h2 = currRing->idroot->get(n,myynest);
464  }
465  if (h2==NULL) return h;
466  return h2;
467}
468
469idhdl ggetid(const char *n)
470{
471  idhdl h = IDROOT->get(n,myynest);
472  if ((h!=NULL)&&(IDLEV(h)==myynest)) return h;
473  idhdl h2=NULL;
474  if (currRing!=NULL)
475  {
476    h2 = currRing->idroot->get(n,myynest);
477  }
478  if (h2!=NULL) return h2;
479  if (h!=NULL) return h;
480  if (basePack!=currPack)
481    return basePack->idroot->get(n,myynest);
482  return NULL;
483}
484
485void ipListFlag(idhdl h)
486{
487  if (hasFlag(h,FLAG_STD)) PrintS(" (SB)");
488#ifdef HAVE_PLURAL
489  if (hasFlag(h,FLAG_TWOSTD)) PrintS(" (2SB)");
490#endif
491}
492
493lists ipNameList(idhdl root)
494{
495  idhdl h=root;
496  /* compute the length */
497  int l=0;
498  while (h!=NULL) { l++; h=IDNEXT(h); }
499  /* allocate list */
500  lists L=(lists)omAllocBin(slists_bin);
501  L->Init(l);
502  /* copy names */
503  h=root;
504  l=0;
505  while (h!=NULL)
506  {
507    /* list is initialized with 0 => no need to clear anything */
508    L->m[l].rtyp=STRING_CMD;
509    L->m[l].data=omStrDup(IDID(h));
510    l++;
511    h=IDNEXT(h);
512  }
513  return L;
514}
515
516/*
517* move 'tomove' from root1 list to root2 list
518*/
519static int ipSwapId(idhdl tomove, idhdl &root1, idhdl &root2)
520{
521  idhdl h;
522  /* search 'tomove' in root2 : if found -> do nothing */
523  h=root2;
524  while ((h!=NULL) && (h!=tomove)) h=IDNEXT(h);
525  if (h!=NULL) return FALSE; /*okay */
526  /* search predecessor of h in root1, remove 'tomove' */
527  h=root1;
528  if (tomove==h)
529  {
530    root1=IDNEXT(h);
531  }
532  else
533  {
534    while ((h!=NULL) && (IDNEXT(h)!=tomove)) h=IDNEXT(h);
535    if (h==NULL) return TRUE; /* not in the list root1 -> do nothing */
536    IDNEXT(h)=IDNEXT(tomove);
537  }
538  /* add to root2 list */
539  IDNEXT(tomove)=root2;
540  root2=tomove;
541  return FALSE;
542}
543
544void  ipMoveId(idhdl tomove)
545{
546  if ((currRing!=NULL)&&(tomove!=NULL))
547  {
548    if (((QRING_CMD!=IDTYP(tomove)) && RingDependend(IDTYP(tomove)))
549    || ((IDTYP(tomove)==LIST_CMD) && (lRingDependend(IDLIST(tomove)))))
550    {
551      /*move 'tomove' to ring id's*/
552      if (ipSwapId(tomove,IDROOT,currRing->idroot))
553      ipSwapId(tomove,basePack->idroot,currRing->idroot);
554    }
555    else
556    {
557      /*move 'tomove' to global id's*/
558      ipSwapId(tomove,currRing->idroot,IDROOT);
559    }
560  }
561}
562
563const char * piProcinfo(procinfov pi, const char *request)
564{
565  if(pi == NULL) return "empty proc";
566  else if (strcmp(request, "libname")  == 0) return pi->libname;
567  else if (strcmp(request, "procname") == 0) return pi->procname;
568  else if (strcmp(request, "type")     == 0)
569  {
570    switch (pi->language)
571    {
572      case LANG_SINGULAR: return "singular"; break;
573      case LANG_C:        return "object";   break;
574      case LANG_NONE:     return "none";     break;
575      default:            return "unknow language";
576    }
577  }
578  else if (strcmp(request, "ref")      == 0)
579  {
580    char p[8];
581    sprintf(p, "%d", pi->ref);
582    return omStrDup(p);  // MEMORY-LEAK
583  }
584  return "??";
585}
586
587void piCleanUp(procinfov pi)
588{
589  (pi->ref)--;
590  if (pi->ref <= 0)
591  {
592    if (pi->libname != NULL) // OB: ????
593      omFree((ADDRESS)pi->libname);
594    if (pi->procname != NULL) // OB: ????
595      omFree((ADDRESS)pi->procname);
596
597    if( pi->language == LANG_SINGULAR)
598    {
599      if (pi->data.s.body != NULL) // OB: ????
600        omFree((ADDRESS)pi->data.s.body);
601    }
602    if( pi->language == LANG_C)
603    {
604    }
605    memset((void *) pi, 0, sizeof(procinfo));
606    pi->language=LANG_NONE;
607  }
608}
609
610BOOLEAN piKill(procinfov pi)
611{
612  Voice *p=currentVoice;
613  while (p!=NULL)
614  {
615    if (p->pi==pi && pi->ref <= 1)
616    {
617      Warn("`%s` in use, can not be killed",pi->procname);
618      return TRUE;
619    }
620    p=p->next;
621  }
622  piCleanUp(pi);
623  if (pi->ref <= 0)
624    omFreeBin((ADDRESS)pi,  procinfo_bin);
625  return FALSE;
626}
627
628void paCleanUp(package pack)
629{
630  (pack->ref)--;
631  if (pack->ref < 0)
632  {
633#ifndef HAVE_STATIC
634    if( pack->language == LANG_C)
635    {
636      Print("//dlclose(%s)\n",pack->libname);
637#ifdef HAVE_DYNAMIC_LOADING
638      dynl_close (pack->handle);
639#endif /* HAVE_DYNAMIC_LOADING */
640    }
641#endif /* HAVE_STATIC */
642    omfree((ADDRESS)pack->libname);
643    memset((void *) pack, 0, sizeof(sip_package));
644    pack->language=LANG_NONE;
645  }
646}
647
648void proclevel::push(char *n)
649{
650  //Print("push %s\n",n);
651  proclevel *p=(proclevel*)omAlloc0(sizeof(proclevel));
652  p->cRing=currRing;
653  p->cRingHdl=currRingHdl;
654  p->name=n;
655  p->cPackHdl=currPackHdl;
656  p->cPack=currPack;
657  p->next=this;
658  procstack=p;
659}
660void proclevel::pop()
661{
662  //Print("pop %s\n",name);
663  //if (currRing!=::currRing) PrintS("currRing wrong\n");;
664  //::currRing=this->currRing;
665  //if (r==NULL) Print("set ring to NULL at lev %d(%s)\n",myynest,name);
666  //::currRingHdl=this->currRingHdl;
667  //if((::currRingHdl==NULL)||(IDRING(::currRingHdl)!=(::currRing)))
668  //  ::currRingHdl=rFindHdl(::currRing,NULL,NULL);
669  //Print("restore pack=%s,1.obj=%s\n",IDID(currPackHdl),IDID(currPack->idroot));
670  currPackHdl=this->cPackHdl;
671  currPack=this->cPack;
672  iiCheckPack(currPack);
673  proclevel *p=this;
674  procstack=next;
675  omFreeSize(p,sizeof(proclevel));
676}
677
678idhdl packFindHdl(package r)
679{
680  idhdl h=basePack->idroot;
681  while (h!=NULL)
682  {
683    if ((IDTYP(h)==PACKAGE_CMD)
684        && (IDPACKAGE(h)==r))
685      return h;
686    h=IDNEXT(h);
687  }
688  return NULL;
689}
Note: See TracBrowser for help on using the repository browser.